Хотя NGINX намного моложе других веб-серверов, он быстро стал популярным выбором. Частично его успех основан на том, что он является предпочтительным веб-сервером для тех, кто ищет легкий и эффективный веб-сервер.
В сегодняшней статье мы возьмем готовый экземпляр NGINX и настроим его так, чтобы получить больше от уже высокопроизводительного веб-сервера. Хотя эта статья не является полным руководством по настройке, она должна дать читателям четкое представление об основах настройки и нескольких общих параметрах настройки NGINX.
Однако прежде чем приступить к настройке, давайте сначала установим NGINX.
Установка NGINX
В этой статье мы будем запускать NGINX на сервере под управлением Ubuntu Linux, поэтому мы можем выполнить установку с помощью команды apt-get .
|
1
|
root@nginx-test:~# apt-get install nginx |
На этом шаге будет установлена общая установка NGINX, в которой уже есть некоторые параметры настройки, установленные из коробки. Однако установка NGINX по умолчанию не предлагает много возможностей для обслуживания контента. Чтобы создать реалистичное веб-приложение, давайте развернем пример сайта с GitHub.
|
1
2
3
4
5
6
7
|
root@nginx-test:~# git clone https://github.com/BlackrockDigital/startbootstrap-clean-blog.git /var/www/htmlCloning into '/var/www/html'...remote: Counting objects: 308, done.remote: Total 308 (delta 0), reused 0 (delta 0), pack-reused 308Receiving objects: 100% (308/308), 1.98 MiB | 0 bytes/s, done.Resolving deltas: 100% (119/119), done.Checking connectivity... done. |
При настройке производительности важно понимать тип приложения, которое настраивается. В случае NGINX важно знать, настраиваете ли вы статический контент или динамический контент, обслуживаемый последующим приложением. Разница между этими двумя типами содержимого может изменить параметры настройки, а также значения этих параметров.
В этой статье мы настроим NGINX для обслуживания статического HTML-контента. Хотя большинство параметров будут применяться к NGINX в целом, не все из них будут. Лучше всего использовать эту статью в качестве руководства для вашей собственной настройки и тестирования.
Теперь, когда наш базовый экземпляр установлен и развернут пример сайта, давайте посмотрим, насколько хорошо выполняется стандартная установка NGINX.
Установление базовой линии
Один из первых шагов в настройке производительности — установить единицу измерения. В этой статье мы будем использовать инструмент нагрузочного тестирования HTTP ApacheBench , также известный как ab для генерации тестового трафика в нашу систему NGINX.
Этот инструмент нагрузочного тестирования очень прост и полезен для веб-приложений. ApacheBench предоставляет довольно много опций для различных типов сценариев нагрузочного тестирования; однако в этой статье мы проведем тестирование довольно просто.
Мы будем выполнять команду ab с установленными параметрами -c (уровень параллелизма) и -n (количество запросов).
|
1
|
$ ab -c 40 -n 50000 http://159.203.93.149/ |
Когда мы выполним ab , мы установим уровень параллелизма ( -c ) на 40 , что означает, что ab будет поддерживать как минимум 40 одновременных HTTP-сеансов с нашим целевым экземпляром NGINX. Мы также установим ограничение на количество запросов, которые нужно сделать с помощью параметра -n . По сути, эти две опции вместе приведут к тому, что ab откроет 40 одновременных HTTP-сессий и отправит как можно больше запросов, пока не достигнет 50000 запросов.
Давайте продолжим и выполним тестовый прогон, чтобы установить базовый уровень и определить, какой показатель мы будем использовать для нашего тестирования сегодня.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
# ab -c 40 -n 50000 http://159.203.93.149/This is ApacheBench, Version 2.3 <$Revision: 1528965 $>Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking 159.203.93.149 (be patient)Completed 5000 requestsCompleted 10000 requestsCompleted 15000 requestsCompleted 20000 requestsCompleted 25000 requestsCompleted 30000 requestsCompleted 35000 requestsCompleted 40000 requestsCompleted 45000 requestsCompleted 50000 requestsFinished 50000 requestsServer Software: nginx/1.10.0Server Hostname: 159.203.93.149Server Port: 80Document Path: /Document Length: 8089 bytesConcurrency Level: 40Time taken for tests: 16.904 secondsComplete requests: 50000Failed requests: 0Total transferred: 420250000 bytesHTML transferred: 404450000 bytesRequests per second: 2957.93 [#/sec] (mean)Time per request: 13.523 [ms] (mean)Time per request: 0.338 [ms] (mean, across all concurrent requests)Transfer rate: 24278.70 [Kbytes/sec] received |
В приведенном выше выводе есть несколько интересных метрик. Сегодня мы сосредоточимся на метрике « Requests per second . Этот показатель показывает среднее количество запросов, которые наш экземпляр NGINX может обработать за секунду. При настройке параметров мы должны увидеть, как эта метрика идет вверх или вниз.
|
1
|
Requests per second: 2957.93 [#/sec] (mean) |
Из вышесказанного видно, что среднее количество запросов в секунду составило 2957.93 . Это может показаться большим, но мы продолжим увеличивать это число.
При настройке производительности важно не забывать вносить небольшие изменения и сравнивать результаты с базовым уровнем. Для этой статьи наша базовая 2957.93 запросов в секунду. Чтобы параметр был успешным, он должен приводить к увеличению количества запросов в секунду.
С нашим базовым набором показателей давайте продолжим настройку NGINX.
Рабочие темы
Одним из основных параметров настройки в NGINX является количество доступных рабочих потоков . По умолчанию значение этого параметра равно auto , что говорит NGINX о создании одного рабочего потока для каждого процессора, доступного для системы.
Для большинства систем один рабочий процесс на каждый процессор обеспечивает равномерный баланс производительности и снижает накладные расходы. Тем не менее, в этой статье мы пытаемся получить максимальную отдачу от NGINX, обслуживая статический контент, который должен быть довольно низким из-за загрузки ЦП. Давайте посмотрим, сколько запросов в секунду мы можем получить, увеличив это значение.
Для нашего первого теста давайте продолжим и запустим два рабочих процесса для каждого процессора в системе.
Чтобы выяснить, сколько рабочих процессов нам нужно, нам сначала нужно узнать, сколько процессоров доступно для этой системы. Хотя есть много способов сделать это, в этом примере мы будем использовать команду lshw для отображения информации об оборудовании.
|
1
2
3
4
5
|
root@nginx-test:~# lshw -short -class cpuH/W path Device Class Description============================================/0/401 processor Intel(R) Xeon(R) CPU E5-2650L v3 @ 1.80GHz/0/402 processor Intel(R) Xeon(R) CPU E5-2650L v3 @ 1.80GH |
Из вышеприведенного вывода видно, что наша система представляет собой систему с 2 процессорами. Это означает, что для нашего первого теста нам нужно настроить NGINX для запуска в общей сложности 4 рабочих процессов.
Мы можем сделать это, отредактировав параметр /etc/nginx/nginx.conf файле /etc/nginx/nginx.conf . Это файл конфигурации NGINX по умолчанию и расположение для всех параметров, которые мы будем настраивать сегодня.
|
1
|
worker_processes auto; |
Выше показано, что для этого параметра установлено значение по умолчанию auto . Давайте продолжим и изменим это значение на 4 .
|
1
|
worker_processes 4; |
После установки нового значения и сохранения файла /etc/nginx/nginx.conf нам потребуется перезапустить NGINX, чтобы изменение конфигурации вступило в силу.
|
1
2
3
4
5
6
7
8
9
|
root@nginx-test:~# service nginx restartroot@nginx-test:~# ps -elf | grep nginx1 S root 23465 1 0 80 0 - 31264 sigsus 20:16 ? 00:00:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;5 S www-data 23466 23465 0 80 0 - 31354 ep_pol 20:16 ? 00:00:00 nginx: worker process5 S www-data 23467 23465 0 80 0 - 31354 ep_pol 20:16 ? 00:00:00 nginx: worker process5 S www-data 23468 23465 0 80 0 - 31354 ep_pol 20:16 ? 00:00:00 nginx: worker process5 S www-data 23469 23465 0 80 0 - 31354 ep_pol 20:16 ? 00:00:00 nginx: worker process0 S root 23471 23289 0 80 0 - 3628 pipe_w 20:16 pts/0 00:00:00 grep --color=auto nginxroot@nginx-test:~# |
Из вышесказанного мы можем видеть, что сейчас есть 4 запущенных процесса с именем nginx: worker process . Это указывает на то, что наше изменение прошло успешно.
Проверка эффекта
Начав работу с дополнительными работниками, давайте снова запустим ab чтобы увидеть, не было ли каких-либо изменений в пропускной способности.
|
1
2
|
# ab -c 40 -n 50000 http://159.203.93.149/ | grep "per second"Requests per second: 3051.40 [#/sec] (mean) |
Кажется, что наше изменение имело очень незначительный эффект: наши исходные Requests per second составляли 2957.93 , а наше новое значение — 3051.40 . Разница здесь примерно на 100 запросов в секунду. Хотя это улучшение, это не тот уровень улучшения, который мы искали.
|
1
|
worker_processes 8; |
Давайте worker_processes значение worker_processes на 8 , в четыре раза превышающее число доступных процессоров. Чтобы изменения вступили в силу, нам снова нужно перезапустить службу NGINX.
|
1
|
root@nginx-test:~# service nginx restart |
После перезапуска службы мы можем продолжить тестирование ab .
|
1
2
|
# ab -c 40 -n 50000 http://159.203.93.149/ | grep "per second"Requests per second: 5204.32 [#/sec] (mean) |
Кажется, что 8 рабочих потоков имеют гораздо более значительный эффект, чем 4 . По сравнению с нашими базовыми показателями мы видим, что с 8 рабочими потоками мы можем обрабатывать примерно на 2250 запросов больше в секунду.
В целом это выглядит как значительное улучшение по сравнению с нашей базовой линией. Вопрос в том, насколько больше улучшений мы увидим, если еще больше увеличить количество рабочих потоков?
Помните, что лучше вносить небольшие постепенные изменения и измерять производительность, увеличивая каждый шаг. Для этого параметра я просто увеличил бы его значение кратным двум и повторно запускал тест каждый раз. Я повторял бы этот процесс, пока количество запросов в секунду больше не увеличивается. Однако для этой статьи мы продолжим и перейдем к следующему параметру, оставив значение worker_processes равным 8 .
Рабочие связи
Следующий параметр, который мы собираемся настроить, — это конфигурация worker_connections в NGINX. Это значение определяет максимальное количество сеансов TCP на одного работника. Увеличивая это значение, мы надеемся, что мы сможем увеличить производительность каждого рабочего процесса.
Параметр worker_connections находится в блоке events в /etc/nginx/nginx.conf конфигурации /etc/nginx/nginx.conf .
|
1
2
3
4
|
events { worker_connections 768; # multi_accept on;} |
Настройка по умолчанию для установки UGNTU NGINX — 768 . В этом первом тесте мы попытаемся изменить этот параметр на 1024 и измерить влияние этого изменения.
|
1
2
3
4
|
events { worker_connections 1024; # multi_accept on;} |
Как и предыдущее изменение конфигурации, чтобы эта настройка вступила в силу, мы должны перезапустить службу NGINX.
|
1
|
root@nginx-test:~# service nginx restart |
После перезапуска NGINX мы можем запустить еще один тест с помощью команды ab .
|
1
2
|
# ab -c 40 -n 50000 http://159.203.93.149/ | grep "per second"Requests per second: 6068.41 [#/sec] (mean) |
Еще раз, наше изменение параметров привело к значительному увеличению производительности. С небольшим изменением worker_connections мы смогли увеличить нашу пропускную способность на 800 запросов в секунду.
Увеличение рабочих потоков дальше
Если небольшое изменение в worker_connections может добавить 800 запросов в секунду, какое влияние окажет гораздо большее изменение? Единственный способ выяснить это — изменить параметр и протестировать снова.
Давайте продолжим и изменим значение worker_connections на 4096 .
|
1
2
3
4
5
6
|
worker_rlimit_nofile 4096;events { worker_connections 4096; # multi_accept on;} |
Мы видим, что значение worker_connections равно 4096 , но есть и другой параметр, значение которого равно 4096 . Параметр worker_rlimit_nofile используется для определения максимального количества открытых файлов на рабочий процесс. Причина, по которой этот параметр теперь указан, заключается в том, что при настройке количества подключений на одного работника необходимо также настроить ограничения для открытого файла.
С NGINX каждое открытое соединение соответствует по крайней мере одному или иногда двум открытым файлам. Устанавливая максимальное количество соединений в 4096 , мы по сути определяем, что каждый работник может открывать до 4096 файлов. Без установки для worker_rlimit_nofile по крайней мере, такого же, что и worker_connections , мы можем фактически снизить производительность, поскольку каждый работник будет пытаться открывать новые файлы и будет отклонен из-за ограничений открытого файла или 1024 .
С этими настройками давайте продолжим тестирование, чтобы увидеть, как наши изменения влияют на NGINX.
|
1
2
|
# ab -c 40 -n 50000 http://159.203.93.149/ | grep "per second"Requests per second: 6350.27 [#/sec] (mean) |
Судя по результатам прогона ab , мы смогли добавить около 300 запросов в секунду. Хотя это может и не быть столь значительным изменением, как наши более ранние 800 запросов в секунду, это все же является улучшением пропускной способности. Таким образом, мы оставим этот параметр как есть, чтобы перейти к следующему пункту.
Тюнинг для нашей рабочей нагрузки
При настройке NGINX или чего-либо еще по этому вопросу важно учитывать рабочую нагрузку настраиваемой службы. В нашем случае NGINX просто обслуживает статические HTML-страницы. Существует набор параметров настройки, которые очень полезны при обслуживании статического HTML.
|
1
2
3
4
|
http { open_file_cache max=1024 inactive=10s; open_file_cache_valid 120s; |
Параметры open_file_cache в файле /etc/nginx/nginx.conf используются для определения того, как долго и сколько файлов NGINX может сохранять открытыми и кэшироваться в памяти.
По сути, эти параметры позволяют NGINX открывать наши HTML-файлы во время первого HTTP-запроса и сохранять эти файлы открытыми и кэшированными в памяти. По мере выполнения последующих HTTP-запросов NGINX может использовать этот кеш вместо повторного открытия наших исходных файлов.
Выше мы определяем параметр open_file_cache чтобы NGINX мог кэшировать max 1024 открытых файла. Однако из этих файлов кеш будет признан недействительным, если к ним не будет доступа в течение 10 секунд. Параметр open_file_cache_valid определяет временной интервал, чтобы проверить, все ли действительные кэшированные файлы все еще действительны; в этом случае каждые 120 секунд.
Эти параметры должны значительно сократить количество раз, когда NGINX должен открывать и закрывать наши статические HTML-файлы. Это означает меньшую общую работу на запрос, что должно означать более высокую пропускную способность. Давайте проверим нашу теорию с помощью еще одного запуска команды ab .
|
1
2
|
# ab -c 40 -n 50000 http://159.203.93.149/ | grep "per second"Requests per second: 6949.42 [#/sec] (mean) |
При увеличении почти 600 запросов в секунду параметры open_file_cache эффект. Хотя этот параметр может показаться очень полезным, важно помнить, что этот параметр работает в нашем примере, потому что мы просто обслуживаем статический HTML. Если бы мы тестировали приложение, которое каждый раз обслуживало динамический контент, эти параметры могут привести к ошибкам рендеринга для конечных пользователей.
Резюме
На данный момент мы взяли готовый экземпляр NGINX, измерили базовый показатель 2957.93 запросов в секунду и настроили этот экземпляр до 6949.42 запросов в секунду. В результате мы получили примерно 4000 запросов в секунду. Мы сделали это, не только изменив несколько ключевых параметров, но и поэкспериментировав с этими параметрами.
Хотя в этой статье были затронуты только некоторые ключевые параметры NGINX, методы, используемые в этой статье для изменения и измерения воздействия, можно использовать с другими общими параметрами настройки NGINX, такими как включение кэширования содержимого и сжатия gzip . Дополнительные параметры настройки приведены в Руководстве администратора NGINX, в котором содержится довольно много информации об управлении NGINX и его настройке для различных рабочих нагрузок.
| Ссылка: | Настройка NGINX от нашего партнера JCG Бена Кейна в блоге Codeship Blog . |