Развертывание
Функция bottle run(), при вызове без параметров, запускает локальный сервер разработки на порту 8080. Вы можете получить доступ и протестировать своё приложение по адресу http://localhost:8080/, если вы находитесь на том же хосте.
Чтобы сделать приложение доступным извне, укажите IP-адрес интерфейса, на котором должен слушать сервер (например, run(host='192.168.0.1')) или позвольте серверу прослушивать все интерфейсы сразу (например, run(host='0.0.0.0')). Порт прослушивания можно изменить аналогичным образом, но вам потребуются права root или администратора, чтобы выбрать порт ниже 1024. Порт 80 является стандартным для HTTP-серверов:
run(host='0.0.0.0', port=80) # Listen to HTTP requests on all interfaces
Параметры сервера
Встроенный сервер по умолчанию основан на wsgiref WSGIServer. Этот не-потоковый HTTP-сервер отлично подходит для разработки и раннего производства, но может стать узким местом производительности при увеличении нагрузки на сервер. Существует три способа устранения этой проблемы:
- Используйте другой сервер, который является многопоточным или асинхронным.
- Запустите несколько процессов сервера и распределите нагрузку с помощью балансировщика нагрузки.
- Сделайте и то, и другое.
Многопоточные серверы — это «классический» способ. Они очень надёжны, достаточно быстры и просты в управлении. В качестве недостатка они могут обрабатывать только ограниченное количество подключений одновременно и использовать только один процессорный ядро из-за «глобальной блокировки интерпретатора» (GIL). Это не вредит большинству приложений, они в основном ожидают сетевого ввода/вывода, но может замедлить задачи, требующие интенсивной обработки ЦП (например, обработку изображений).
Асинхронные серверы очень быстрые, могут обрабатывать практически неограниченное количество одновременных подключений и просты в управлении, но могут быть немного сложнее. Чтобы в полной мере использовать их возможности, необходимо соответствующим образом спроектировать своё приложение и понять концепции конкретного сервера.
Многопроцессорные (fork) серверы не ограничены 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 | Асинхронный (только сторона сети), написанный на C |
| tornado | tornado | Асинхронный, используется в некоторых частях Facebook |
| twisted | twisted | Асинхронный, хорошо протестированный, но… запутанный |
| meinheld | meinheld | Асинхронный, частично написанный на C |
| bjoern | bjoern | Асинхронный, очень быстрый и написанный на C |
| 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.12/deployment.html