Инструкция с примерами и комментариями по запуску асинхронного веб-сервера aiohttp с помощью gunicorn за nginx.
💾Установка программ
Начать необходимо с установки необходимых программ. Примеры основаны на Ubuntu.
Установка актуальной версии nginx описана здесь.
Установка других пакетов:
[code commandline]
1 2 |
sudo apt-get update sudo apt-get install python3 virtualenv supervisor |
[/code]
📦Разворачивание проекта
Предположим, что проект уже готов и размещен в директории [code]/home/user/aiohttp[/code].
Код, на котором можно протестировать работу представлен ниже. Разместим его в файл [code]app_test.py[/code]:
[code python]
1 2 3 4 5 6 7 |
<span class="kn">from</span> <span class="nn">aiohttp</span> <span class="k">import</span> <span class="n">web</span> <span class="k">def</span> <span class="nf">index</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> <span class="k">return</span> <span class="n">web</span><span class="o">.</span><span class="n">Response</span><span class="p">(</span><span class="n">text</span><span class="o">=</span><span class="s2">"Welcome home!"</span><span class="p">)</span> <span class="n">my_web_app</span> <span class="o">=</span> <span class="n">web</span><span class="o">.</span><span class="n">Application</span><span class="p">()</span> <span class="n">my_web_app</span><span class="o">.</span><span class="n">router</span><span class="o">.</span><span class="n">add_get</span><span class="p">(</span><span class="s1">'/'</span><span class="p">,</span> <span class="n">index</span><span class="p">)</span> |
[/code]
🐍Настроим Python
Работать будем через виртуальное окружение. Переходим в директорию проекта[code]/home/user/aiohttp[/code] и создаем окружение командой:
[code commandline]
1 2 |
cd /home/user/aiohttp virtualenv env --no-site-packages -p python3 |
[/code]
Активируем окружение и дальше работаем под ним:
[code commandline]
1 |
source env/bin/activate |
[/code]
Теперь устанавливаем все необходимые пакеты:
[code commandline]
1 |
pip install aiohttp |
[/code]
🦄Установка и настройка Gunicorn
Устанавливаем командой:
[code commandline]
1 |
pip install gunicorn |
[/code]
Запускаем:
[code commandline]
1 |
gunicorn app_test:my_web_app --bind localhost:8081 --worker-class aiohttp.worker.GunicornWebWorker |
[/code]
Если ошибок нет, тогда можно проверить работу по адресу: http://localhost:8081
Теперь создадим файл конфигурации [code]gunicorn.conf.py[/code], разместим в нем необходимые настройки и поменяем строку запуска для его использования.
[code python]
1 2 3 |
bind = "127.0.0.1:8081" workers = 2 worker_class = "aiohttp.worker.GunicornWebWorker" |
[/code]
Здесь уже указано, что запросы будут обрабатываться двумя рабочими потоками. Если есть желание направить все через сокеты, тогда заменим bind на [code python]bind=»unix:/tmp/apptest.sock»[/code].
Для отладки, в конфиг можно добавить [code]reload=True[/code], после чего gunicorn будет автоматически перезапускаться по факту изменения любого файла проекта.
Строка запуска примет вид:
[code commandline]
1 |
gunicorn app_test:my_web_app -c gunicorn.conf.py |
[/code]
Настройка supervisor
Для работы gunicorn в режиме демона, атоматического запуска и перезапуска сервиса необходимо настроить supervisor. Программа написана на Python 2+ и поддерживает только 2 версию.
Есть другие альтернативы, такие как systemd, upstart, runit, но все они требуют более сложной настройки или наличия программ-зависимостей в системе.
Для проверки наличия установленного сервиса, запустим его командой (если ошибок нет, значит все в порядке):
[code commandline]
1 |
sudo service supervisor restart |
[/code]
Файлы конфигурации лежат в директории [code]/etc/supervisor/conf.d/[/code], где создадим свой файл [code]apptest.conf[/code] и добавим в него:
[code ini]
1 2 3 4 5 6 7 |
[program:apptest] command=/home/user/aiohttp/env/bin/gunicorn main:application -c /home/user/aiohttp/gunicorn.conf.py directory=/home/user/aiohttp user=nobody autostart=true autorestart=true #redirect_stderr=true |
[/code]
Если хотите все сообщения лить в лог ошибок, тогда включите [code]redirect_stderr=true[/code]
Теперь прочитаем новый конфиг командой:
[code commandline]
1 |
supervisorctl reread |
[/code]
Если мы видим наше приложение, тогда применим новую конфигурацию командой:
[code commandline]
1 |
supervisorctl update |
[/code]
Посмотреть статус программ можно командой:
[code batch]
1 |
supervisorctl |
[/code]
Помощь по командам внутри supervisorctl доступна по команде help.
Если все сделано верно, тогда можно проверить работу по адресу: http://localhost:8081
Для настройки ведения логов необходимо добавить в конфиг supervisor следующие строки (затем перечитать конфиги, обновить и перезапустить приложение):
[code ini]
1 2 |
stderr_logfile=/var/log/supervisor/apptest.err.log stdout_logfile=/var/log/supervisor/apptest.out.log |
[/code]
Перезапуск приложения из командной строки:
[code commandline]
1 |
supervisorctl restart apptest |
[/code]
В Ubuntu 16+ есть проблема, из-за которой supervisor не запускается автоматически после перезагрузки. Для решения этой проблемы необходимо выполнить следующие команды:
[code commandline]
1 2 |
systemctl enable supervisor systemctl start supervisor |
[/code]
Настройка Nginx
Добавим конфиг сайта [code]/etc/nginx/conf.d/apptest.conf[/code] с содержимым:
[code apacheconf]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
upstream apptest_server { # for UNIX domain socket setups server unix:/tmp/apptest.sock fail_timeout=0; } server { listen 80; server_name apptest.local; # path for static files root /home/user/aiohttp/static; location / { # checks for static file, if not found proxy to app try_files $uri @proxy_to_app; } location @proxy_to_app { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://127.0.0.1:8081; #proxy_pass http://apptest_server; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } |
[/code]
upstream apptest_server показан для примера, при желании завернуть все через сокеты, чтобы gunicorn не занимал портов.
Данные примеры будут работать только на Linux и Unix-подобных системах. На Windows это не повторить.
💬В комментариях напишите, нужен ли вообще этот асинхронный сервер?