Як працює http-сервер nginx
Як працює HTTP-сервер nginx
Вже довгий час Apache є найбільш популярним HTTP-сервером з відкритим вихідним кодом. Але він може бути занадто громіздким для деяких pадач. І тут на сцену виходять нові гравці - легковагі, асинхронні HTTP-сервери, одним з яких є nginx.
Тепер, коли у мене було два варіанти, залишалося найскладніше - вибрати найбільш підходящий для мого випадку. Це складний вибір, тому що обидва мають практично однакові можливості (хоча nginx також може використовуватися як поштовий проксі-сервер, я не брав до уваги це в порівнянні). Обидва використовуються на високо відвідуваних сайтах, наприклад, YouTube використовує Lighttpd, а Rambler - nginx. Обидва мають досить гарну документацію, в тому числі nginx має документацію російською. В результаті для себе я зупинився на nginx з наступних причин:
Перш ніж звернутися до розгляду безпосередньо сервера nginx, розглянемо, чим відрізняється асинхронний (подієвий) підхід від паралельної обробки з'єднань в окремих процесах, або потоках.
У найпростішому випадку при паралельній обробці з'єднань основний процес займається очікуванням вхідних з'єднань і після цього віддає всю роботу по обробці нового з'єднання дочірньому процесу, або окремому потоку. У даного підходу є такі переваги:
n Це проста модель для програмування сервера і модулів.
n Кожне з'єднання обробляється незалежно, і таким чином можлива довга обробка даних, виконувана в одному процесі (потоці), не впливає на інші.
n Такий підхід погано масштабується. Наприклад 1000 одночасно відкритих з'єднань може бути цілком нормальним числом, але 1000 одночасно працюючих процесів, або потоків, можуть бути проблемою.
При асинхронної обробки в разі одного процесу з одним потоком використовується спеціальний системний виклик здійснюють диспетчеризацію відкритих сокетів і дескрипторів файлів. Цей системний виклик повертає тільки сокети і дескриптори, готові для відкриття з'єднання, читання або запису. Так як основний час зазвичай витрачається на очікування введення-виведення і швидкість роботи процесора з пам'яттю у багато разів вище швидкості введення-виведення, можна встигати виконувати необхідну обробку даних, в той час як система очікує їх нову порцію. Переваги такого підходу:
n Для багатьох застосувань тільки один процес з одним потоком може обробляти більше з'єднань, ніж в разі паралельної обробки.
n Так як один процес з одним потоком може обробляти відразу декілька з'єднань для обробки більшої кількості з'єднань, використовується менше ресурсів.
n Програмування асинхронних додатків може бути складніше, ніж додатків з паралельною обробкою.
n У разі використання тільки одного процесу з одним потоком він може погано масштабироваться, хоча і краще, ніж при паралельній обробці.
n У найпростішому випадку асинхронний підхід не може використовуватися, якщо необхідна довга обробка даних.
Як можна помітити, обидва підходи мають свої переваги і недоліки. Щоб об'єднати гідності і зменшити недоліки з обох підходів, в даний час для асинхронних мережних додатків найбільш популярний гібридний підхід, при якому кілька асинхронних додатків працюють паралельно в окремих процесах, або потоках. Тепер розглянемо, як це працює в nginx.
Збірка і установка
Хоча nginx вже доступний в пакетах для останніх версій Ubuntu Linux, я вирішив збирати його з вихідних, тому що хотів використовувати більш свіжу стабільну версію і модуль mod_wsgi для підтримки WSGI-протоколу Python. Якщо вам не потрібно збирати nginx з mod_wsgi, ви можете пропустити всі місця, де він згадується.
Отже, для збірки нам знадобиться вихідний код nginx, вихідний код бібліотеки сумісних з Perl регулярних виразів (PCRE) і вихідний код модуля mod_wsgi. Тут ми використовуємо самі останні, на даний момент, версії mod_wsgi і бібліотеки PCRE. При використанні більш старих версій PCRE версія не повинна бути нижче 4.4:
$ Tar -xzf nginx-0.6.32.tar.gz
$ Tar -xjf pcre-7.8.tar.bz2
$ Tar -xzf mod_wsgi.tar.gz
$ Mv mod_wsgi-8994b058d2db mod_wsgi
if (r-> method == NGX_HTTP_GET || r-> method == NGX_HTTP_HEAD)
if (rc! = NGX_OK rc! = NGX_AGAIN)
І потім докладемо:
$ Patch -d mod_wsgi -p0 Для складання Nginx з SSL також необхідно встановити бібліотеку OpenSSL і для використання модуля ngx_http_gzip_module бібліотеку zlib. Для складання mod_wsgi знадобиться встановити пакет python-dev: $ Sudo apt-get install libssl-dev $ Sudo apt-get install zlib1g-dev $ Sudo apt-get install python-dev $ Chmod a + x nginx.sh Розглянемо опції по порядку: n Опція user описує, від імені якого користувача і групи будуть виконуватися робочі процеси. n Опція worker_processes визначає кількість робочих процесів. Кількість робочих процесів - параметр, який впливає на продуктивність і в основному залежить від очікуваної навантаження на сервер і необхідної функціональності сайтів. У найпростішому випадку може бути тільки один робочий процес, але якщо використовується компресія даних, або SSL, то їх кількість може дорівнювати кількості процесорів або в два рази більшій кількості. В даному випадку я вибрав 4 робочих процесу, тому що приклад зі статичним сайтом використовує і компресію, і SSL і запускається на двухпроцессорной машині. У разі якщо використовуються не зовсім властиві nginx синхронні модулі, як наприклад mod_wsgi, потрібно вибрати кількість робочих процесів в залежності від очікуваної кількості одночасних запитів і швидкості їх обробки. n Опції error_log і pid описують відповідно шлях до файлу журналу помилок разом з рівнем логгінг і шлях до файлу, в якому буде зберігатися ідентифікатор головного процесу сервера. n Секція events описує опції, пов'язані з обробкою подій. Опція worker_connections описує обмеження на кількість одночасно оброблюваних робочими процесами з'єднань. Таким чином, в разі статичного сайту максимальну кількість одночасних з'єднань з сервером можна розрахувати за формулою: worker_processes * worker_connections. Також в цій секції можна вибрати метод обробки подій, наприклад use epoll, і інші параметри, пов'язані з обробкою подій. n Секція http описує конфігурацію HTTP-сервера і всіх сайтів. Опції include і default_type описують каталог MIME-типів і тип за замовчуванням відповідно. Опція charset визначає кодування, яка буде додана в заголовок відповіді Content-Type. Якщо її не вказувати, браузери будуть використовувати власні кодування за замовчуванням як кодування контенту. Опція server_tokens управляє висновком номера версії сервера у відповідях. Опція sendfile включає використання системного виклику, оптимизирующего посилку файлів. Набір опцій, що починаються на gzip, описує параметри стиснення відповідей. Набір опцій, що починаються на SSL, описує налаштування SSL-сесій. Опція include підключає інший файл конфігурації, в даному випадку безпосередньо конфігурацію сайту. Конфігурація сайту може виглядати наступним чином: server_name example.ru * .example.ru; error_log /var/log/nginx/example.ru/error.log info; if ($ host! = "example.ru")
error_log /var/log/nginx/example.ru/error.log info; auth_basic "Example admin place"; В даному випадку файл /etc/nginx/example.ru.conf описує дві версії одного сайту - звичайну HTTP-версію і HTTPS-версію, захищену паролем. Секції server описують конфігурацію віртуальних серверів. Розглянемо опції докладніше: n Опція server_name задає ім'я і псевдоніми сайту. n Опції error_log і access_log визначають шлях до файлу журналу помилок з рівнем логгірованія і журналу запитів відповідно. n Секція location об'єднує конфігураційні параметри в залежності від URI запиту. n Опції root і index описують кореневу директорію сайту і ім'я індексного файлу за замовчуванням. n Опції if і rewrite використовуються для зміни URI запиту. В даному прикладі всі запити для інших доменів перенаправляються на example.ru. n Опції, що починаються з ssl_, описують шлях до SSL-сертифікату та приватному ключу відповідно. Часто HTTP-сервер є лише посередником (проксі), що стоять перед іншим HTTP-сервером. Наприклад, така конфігурація потрібна, якщо один із сайтів зроблений із застосуванням технології, яка вже має свій HTTP-сервер, або посередник використовується як балансувальник навантаження для декількох стоять за ним серверів. У nginx ця функціональність підтримується модулем ngx_http_proxy_module. proxy_set_header Host $ host; proxy_set_header X-Real-IP $ remote_addr; proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for; Ці опції встановлюють додаткові заголовки, які будуть передані допоміжному сервера, і підключають файл конфігурації сайту. Конфігурація сайту може бути такою: error_log /var/log/nginx/zope3.example.ru/error.log info; error_page 502 503 504 /maintenance.html; fastcgi_param SCRIPT_FILENAME /home/www/php.example.ru/data$fastcgi_script_name; Крім вже відомих опцій, тут є секція, яка визначає дії для всіх шляхів, що закінчуються на .php: n Опція fastcgi_index задає ім'я індексного файлу для FastCGI. n Опцією include ми підключаємо файл з параметрами, які будуть передаватися в FastCGI-запитах. На жаль, ми не можемо один раз підключити ці параметри на більш верхньому рівні, тому що наступна опція fastcgi_param, яка в свою чергу ставить ще один додатковий параметр, скасовує всі визначення параметрів більш високого рівня. Налаштовуємо Python з WSGI wsgi_var REQUEST_METHOD $ request_method; wsgi_var QUERY_STRING $ query_string; wsgi_var CONTENT_TYPE $ content_type; wsgi_var CONTENT_LENGTH $ content_length; wsgi_var SERVER_NAME $ server_name; wsgi_var SERVER_PORT $ server_port; wsgi_var SERVER_PROTOCOL $ server_protocol; wsgi_var REQUEST_URI $ request_uri; wsgi_var DOCUMENT_URI $ document_uri; wsgi_var DOCUMENT_ROOT $ document_root; wsgi_var SERVER_SOFTWARE $ nginx_version; wsgi_var REMOTE_ADDR $ remote_addr; wsgi_var REMOTE_PORT $ remote_port; wsgi_var SERVER_ADDR $ server_addr; wsgi_var REMOTE_USER $ remote_user; Після цього необхідно додати в /etc/nginx/nginx.conf в секцію http опції: Тепер зробимо WSGI-скрипт для підключення Trac і покладемо його як /home/www/wsgi.example.ru/wsgi.py, не забуваючи зробити виконуваним: І останній момент - конфігурація сайту: error_log /var/log/nginx/wsgi.example.ru/error.log info; Тут опція wsgi_pass визначає ім'я скрипта, який буде виконуватися в рамках робочого процесу. Відповідно, так як скрипти виконуються синхронно в рамках робочих процесів, для оптимізації продуктивності сайту з WSGI, можливо, доведеться збільшити значення опції worker_processes в nginx.conf. def application (environ, start_response): return [ "Hello world!"] Таким чином, протокол дозволяє, наприклад, почати налагоджувати веб-додаток, використовуючи стандартний пакет wsgiref (з'явився в Python 2.5), і потім перейти на mod_wsgi (з n ginx, або Apache) або HTTP-сервер з асинхронного каркаса Twisted.Схожі статті