Spec-Zone.ru › Bottle 0.11

Развертывание

Функция bottle run(), при вызове без параметров, запускает локальный сервер разработки на порту 8080. Вы можете получить доступ и протестировать своё приложение по адресу http://localhost:8080/, если вы на том же хосте.

Чтобы сделать ваше приложение доступным для внешнего мира, укажите IP-адрес интерфейса, на котором сервер должен прослушивать подключения (например, run(host='192.168.0.1')) или позвольте серверу прослушивать все интерфейсы сразу (например, run(host='0.0.0.0')). Порт прослушивания можно изменить аналогичным образом, но для выбора порта ниже 1024 требуются права root или администратора. Порт 80 — стандартный для HTTP-серверов:

run(host='0.0.0.0', port=80) # Listen to HTTP requests on all interfaces

Параметры сервера

Встроенный сервер по умолчанию основан на wsgiref WSGIServer. Этот не-потоковый HTTP-сервер отлично подходит для разработки и ранней эксплуатации, но может стать узким местом в производительности при увеличении нагрузки на сервер. Есть три способа устранить эту проблему:

  • Используйте другой сервер, который либо многопоточный, либо асинхронный.
  • Запустите несколько процессов сервера и распределите нагрузку с помощью балансировщика нагрузки.
  • Сделайте и то, и другое.

Многопоточные серверы — это «классический» способ. Они очень надёжные, достаточно быстрые и простые в управлении. В качестве недостатка, они могут обрабатывать только ограниченное число подключений одновременно и использовать только один процессорный ядро из-за «глобальной блокировки интерпретатора» (GIL). Это не вредит большинству приложений, они в основном ждут сетевого ввода-вывода, но может замедлить задачи, требующие интенсивных вычислений на процессоре (например, обработка изображений).

Асинхронные серверы очень быстрые, могут обрабатывать практически неограниченное количество одновременных подключений и просты в управлении, но могут быть немного сложнее в использовании. Чтобы полностью использовать их потенциал, вам нужно разработать ваше приложение соответствующим образом и понять концепции конкретного сервера.

Многопроцессные (виртуальные клонирования) серверы не ограничены GIL и используют более одного процессорного ядра, но коммуникация между экземплярами сервера становится более дорогостоящей. Вам необходима база данных или внешняя система запросов сообщений для обмена состоянием между процессами или разработка вашего приложения так, чтобы оно не нуждалось в общем состоянии. Настройка также немного сложнее, но есть доступные руководства.

Переключение бэкенда сервера

Самый простой способ повышения производительности — установить библиотеку многопоточного сервера, например, paste или cherrypy, и указать Bottle использовать её вместо однопоточного сервера:

bottle.run(server='paste')

Bottle поставляется с множеством готовых адаптеров для наиболее распространённых WSGI-серверов и автоматизирует процесс настройки. Вот неполный список:

Имя Главная страница Описание
cgi Запуск как скрипт CGI
flup flup Запуск как процесс FastCGI
gae gae Помощник для развертывания на Google App Engine
wsgiref wsgiref Однопоточный сервер по умолчанию
cherrypy cherrypy Многопоточный и очень стабильный
paste paste Многопоточный, стабильный, проверенный
rocket rocket Многопоточный
waitress waitress Многопоточный, используется в Pyramid
gunicorn gunicorn Предварительно разветвлённый, частично написанный на С
eventlet eventlet Асинхронная платформа с поддержкой WSGI.
gevent gevent Асинхронный (зелёные нити)
diesel diesel Асинхронный (зелёные нити)
fapws3 fapws3 Асинхронный (только сетевая сторона), написан на С
tornado tornado Асинхронный, используется в некоторых частях Facebook
twisted twisted Асинхронный, хорошо протестированный, но… закрученный
meinheld meinheld Асинхронный, частично написан на С
bjoern bjoern Асинхронный, очень быстрый и написан на С
auto Автоматически выбирает доступный адаптер сервера

Полный список доступен по адресу server_names.

Если для вашего любимого сервера нет адаптера или вам нужен больший контроль над настройкой сервера, вы можете запустить сервер вручную. Обратитесь к документации сервера по запуску WSGI-приложений. Вот пример для paste:

application = bottle.default_app()
from paste import httpserver
httpserver.serve(application, host='0.0.0.0', port=80)

Apache mod_wsgi

Вместо запуска собственного HTTP-сервера внутри Bottle, вы можете подключить приложения Bottle к серверу Apache с помощью mod_wsgi.

Всё, что вам нужно, это файл app.wsgi, который предоставляет объект application. Этот объект используется mod_wsgi для запуска вашего приложения и должен быть WSGI-совместимой вызываемой функцией Python.

Файл /var/www/yourapp/app.wsgi:

# Change working directory so relative paths (and template lookup) work again
os.chdir(os.path.dirname(__file__))

import bottle
# ... build or import your bottle application here ...
# Do NOT use bottle.run() with mod_wsgi
application = bottle.default_app()

Настройка Apache может выглядеть так:

<VirtualHost *>
    ServerName example.com

    WSGIDaemonProcess yourapp user=www-data group=www-data processes=1 threads=5
    WSGIScriptAlias / /var/www/yourapp/app.wsgi

    <Directory /var/www/yourapp>
        WSGIProcessGroup yourapp
        WSGIApplicationGroup %{GLOBAL}
        Order deny,allow
        Allow from all
    </Directory>
</VirtualHost>

Google App Engine

Введено в версии 0.9.

Адаптер сервера gae используется для запуска приложений на Google App Engine. Он работает аналогично адаптеру cgi тем, что не запускает новый HTTP-сервер, но подготавливает и оптимизирует ваше приложение для Google App Engine и гарантирует соответствие его API:

bottle.run(server='gae') # No need for a host or port setting.

Всегда рекомендуется разрешить GAE обслуживать статические файлы напрямую. Вот пример работающего app.yaml:

application: myapp
version: 1
runtime: python
api_version: 1

handlers:
- url: /static
  static_dir: static

- url: /.*
  script: myapp.py

Балансировщик нагрузки (ручная настройка)

Один процесс Python может использовать только один процессор одновременно, даже если доступно больше процессорных ядер. Секрет в том, чтобы распределить нагрузку между несколькими независимыми процессами Python, чтобы использовать все ядра процессора.

Вместо одного сервера приложения Bottle вы запускаете по одному экземпляру на каждое доступное ядро процессора, используя разные локальные порты (localhost:8080, 8081, 8082, ...). Вы можете выбрать любой адаптер сервера, даже асинхронные. Затем высокопроизводительный балансировщик нагрузки действует как обратный прокси и перенаправляет каждый новый запрос на случайный порт, распределяя нагрузку между всеми доступными бэкендами. Таким образом, вы можете использовать все ядра процессора и даже распределить нагрузку между различными физическими серверами.

Один из самых быстрых доступных балансировщиков нагрузки — Pound, но большинство распространённых веб-серверов имеют модуль прокси, который может выполнять эту работу.

Пример Pound:

ListenHTTP
    Address 0.0.0.0
    Port    80

    Service
        BackEnd
            Address 127.0.0.1
            Port    8080
        End
        BackEnd
            Address 127.0.0.1
            Port    8081
        End
    End
End

Пример Apache:

<Proxy balancer://mycluster>
BalancerMember http://192.168.1.50:80
BalancerMember http://192.168.1.51:80
</Proxy>
ProxyPass / balancer://mycluster

Пример Lighttpd:

server.modules += ( "mod_proxy" )
proxy.server = (
    "" => (
        "wsgi1" => ( "host" => "127.0.0.1", "port" => 8080 ),
        "wsgi2" => ( "host" => "127.0.0.1", "port" => 8081 )
    )
)

Хороший старый CGI

CGI-сервер запускает новый процесс для каждого запроса. Это добавляет много издержек, но иногда это единственный вариант, особенно на дешевых хостинговых пакетах. Адаптер сервера cgi фактически не запускает CGI-сервер, но преобразует ваше приложение bottle в действительное CGI-приложение:

bottle.run(server='cgi')

© 2009–2017 Marcel Hellkamp
Licensed under the MIT License.
https://bottlepy.org/docs/0.11/deployment.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API