Tornado — популярный минималистичный фреймворк для разработки web-сервисов с помощью Python. Он часто применяется как для создания обычных сервисов с RESTful-интерфейсом, так и для реализации приложений, использующих Websocket, что идеально реализуется с помощью асинхронных функций языка.
Разработка фреймворка ведется на GitHub. На следующем изображении вы можете видеть, что Tornado активно разрабатывается сообществом:
Настройка сервера для продуктового использования Tornado сопряжена с рядом дополнительных действий, которые требуется выполнить для преодоления ограничений однопоточной природы сервера Tornado — для утилизации всех ядер сервера на многоядерных CPU необходимо запустить несколько экземпляров сервера Tornado и распределить нагрузку между исполняющимися экземплярами с помощью балансировщика нагрузки.
Закончив чтение данного руководства, вы научитесь самостоятельно настраивать минималистичный сервер для для Tornado без лишних компонентов. Ваше приложение будет доступно по защищенному протоколу HTTPS с поддержкой бесплатного сертификата Let’s Encrypt, балансировка трафика между выполняющимися экземплярами приложения Tornado будет осуществляться с помощью Nginx.
Базовая установка сервера для среды исполнения Tornado
Сначала настроим сервер Linux с балансирующим прокси-сервером Nginx и поддержкой сертификата Let’s Encrypt.
Настройка обратного прокси Nginx в CentOS 7 с доступом по SSL, защищенным сертификатом Let’s Encrypt.
Настройка обратного прокси Nginx в Debian 9 Stretch с доступом по SSL, защищенным сертификатом Let’s Encrypt.
Настройка обратного прокси Nginx в Ubuntu 18.04 Bionic Beaver с доступом по SSL, защищенным сертификатом Let’s Encrypt.
Стоит отметить, что в рамках данной настройки возможно использование двух вариантов настройки — с использованием Docker и без его использования. Мы рассмотрим в этой статье варинт настройки без Docker.
Подготовка среды исполнения для Tornado без использования Docker
В этом разделе мы выполним установку Python3, настроим автоматический запуск нескольких экземпляров Tornado, которые будут обрабатывать запросы. Затем, зарместим Tornado за балансирующим прокси-сервером Nginx, который будет осуществлять равномерное распределение нагрузки между серверами Tornado.
Установка Python3
CentOS 7. В CentOS 7 Python 3 устанавливается из дополнительного репозитория Software Collections. По умолчанию используется Python 2.7.
sudo yum install -y centos-release-scl sudo yum install -y rh-python36 sudo yum groupinstall -y 'Development Tools'
Ubuntu 18.04. Установка Python 3 производится из стандартного репозитория:
sudo apt-get update sudo apt-get install -y python3 python3-venv
Debian 9. Установка Python 3 производится из стандартного репозитория:
sudo apt-get update sudo apt-get install -y python3 python3-venv
Подготовка среды для приложения Tornado
На этом шаге создадим VENV для исполнения приложения Tornado:
mkdir application cd application python3 -m venv application_env source application_env/bin/activate echo "tornado" > requirements.txt pip install wheel pip install -r requirements.txt
Тестовое приложение Tornado
Реализуем простое приложение Tornado, которое будем использовать для примера сервиса:
#!/usr/bin/env python import tornado.ioloop import tornado.web import sys class PingHandler(tornado.web.RequestHandler): def get(self): self.write("pong\n") app = tornado.web.Application([(r'/ping', PingHandler)]) if __name__ == "__main__": app.listen(int(sys.argv[1]), address='127.0.0.1') tornado.ioloop.IOLoop.current().start()
Создайте файл service.py
с вышеуказанным содержимым:
cat > service.py #!/usr/bin/env python import tornado.ioloop import tornado.web import sys class PingHandler(tornado.web.RequestHandler): def get(self): self.write("pong\n") app = tornado.web.Application([(r'/ping', PingHandler)]) if __name__ == "__main__": app.listen(int(sys.argv[1]), address='127.0.0.1') tornado.ioloop.IOLoop.current().start() Ctrl^D
Установите права доступа, необходимые для исполнения:
chmod +x service.py
Проверим работу сервиса, запустив его и открыв в браузере http://server:port/ping
:
# запустим в фоновом режиме ./service.py 8888 & # проверим ответ curl http://localhost:8888/ pong # завершим процесс kill %1 [1]+ Завершено ./service.py 8888 # выйдем из VENV deactivate cd ..
Настройка автоматического запуска приложения с помощью systemd
Подготовим скрипт application/run.sh
запуска приложения в рамках VENV со следующим содержимым:
#!/usr/bin/env bash BASEDIR=$(dirname "$0") echo "Executing App in '$BASEDIR'" PORT=$1 source $BASEDIR/application_env/bin/activate python $BASEDIR/service.py $PORT
Установим права на исполнение и протестируем его запуск:
chmod +x application/run.sh ./application/run.sh 8888
Запускать приложение будем с помощью systemd. Для этого создадим параметризованный файл для сервиса:
sudo nano /etc/systemd/system/tornado-app@.service
со следующим содержимым:
[Unit] Description=Tornado App [Service] ExecStart=/home/administrator/application/run.sh %I User=administrator Restart=on-failure Type=simple [Install] WantedBy=multi-user.target
Внимание. Путь, указанный в ExecStart
и имя пользователя, указанное в User
необходимо изменить для соответствия вашей среде.
Теперь проверим работоспособность запуска сервиса через systemd:
sudo systemctl enable tornado-app@8888.service Created symlink from /etc/systemd/system/multi-user.target.wants/tornado-app@8888.service to /etc/systemd/system/tornado-app@.service. sudo systemctl start tornado-app@8888.service ps -x -opid,cmd | grep service 25161 python /home/administrator/application/service.py 8888 sudo systemctl restart tornado-app@8888.service ps -x -opid,cmd | grep service 25166 python /home/administrator/application/service.py 8888 sudo systemctl stop tornado-app@8888.service ps -x -opid,cmd | grep service
Создадим столько серверов Tornado, сколько необходимо. Вы можете захотеть запустить сервисов по количеству ядер, если используете эффективную асинхронную модель разработки, либо запустить сервисов столько, сколько возможно на узле, если асинхронная модель разработки не используется:
for port in $(seq 8889 8900); do sudo systemctl enable tornado-app@$port.service && \ sudo systemctl start tornado-app@$port.service done
Проверим, что все сервисы запустились и работают:
ps -x -ocmd | grep service python /home/administrator/application/service.py 8889 python /home/administrator/application/service.py 8890 python /home/administrator/application/service.py 8891 python /home/administrator/application/service.py 8892 python /home/administrator/application/service.py 8893 python /home/administrator/application/service.py 8894 python /home/administrator/application/service.py 8895 python /home/administrator/application/service.py 8896 python /home/administrator/application/service.py 8897 python /home/administrator/application/service.py 8898 python /home/administrator/application/service.py 8899 python /home/administrator/application/service.py 8900
Перезагрузите сервер для того, чтобы убедиться в том сервис запускается автоматически при старте системы.
Настройка проксирования через Nginx
В секции upstream, которую мы создали при настройке обратного прокси-сервера Nginx, замените содержимое на адреса upstream-сервисов.
Было:
upstream dirlist { ip_hash; # липкая балансировка по IP-клиента server 127.0.0.1:8081; server 127.0.0.1:8082; }
Должно стать:
upstream service { ip_hash; # липкая балансировка по IP-клиента server 127.0.0.1:8888; server 127.0.0.1:8889; server 127.0.0.1:8890; server 127.0.0.1:8891; server 127.0.0.1:8892; server 127.0.0.1:8893; server 127.0.0.1:8894; server 127.0.0.1:8895; server 127.0.0.1:8896; server 127.0.0.1:8897; server 127.0.0.1:8898; server 127.0.0.1:8899; server 127.0.0.1:8900; }
Измените соответствующим образом proxy_pass http://dirlist/;
на proxy_pass http://service/;
. Проверьте корректность конфигурации и перезапустите Nginx:
sudo nginx -t && sudo systemctl restart nginx
Теперь вы можете обращаться к приложению по доменному имени с помощью защищенного протокола HTTPS, который обеспечивается сертификатом Let’s Encrypt.
Что еще сделать после установки?
После установки мы рекомендуем выполнить следующие действия:
- повысить безопасность сервера с помощью тонкой настройки файрвола:
- установить сайт под защиту CloudFlare;
- настроить почтовый сервер, если вы планируете осуществлять отправку почты локально с сервера, а не по SMTP: