1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/mirrors-Puma_old1

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
README.md 31 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 18.04.2025 12:28 f6c362e

Puma: Веб-сервер для Ruby, построенный для параллелизма

Actions Code Climate StackOverflow

Puma — это простой, быстрый, многопоточный и высоко параллельный HTTP 1.1 сервер для приложений на Ruby/Rack.

Построен для скорости и параллелизма

Puma — это сервер для Rack-powered HTTP приложений, написанных на Ruby. Он:

  • Многопоточный. Каждый запрос обрабатывается в отдельном потоке. Это помогает вам обслуживать больше запросов в секунду с меньшим использованием памяти.
  • Многопроцессный. "Предварительное вилочное" в режиме кластера, используя меньше памяти на процесс благодаря механизму copy-on-write.
  • Самостоятельный. С поддержкой SSL, непрерывными перезапусками без простоя и встроенным буфером запросов, вы можете развернуть Puma без использования обратного прокси-сервера.
  • Протестированный в боевых условиях. Наш парсер HTTP унаследован от Mongrel и имеет более 15 лет использования в производственных условиях. Puma в настоящее время является самым популярным Ruby веб-сервером и является стандартным сервером для Ruby on Rails.Изначально был спроектирован как сервер для Rubinius, Puma также хорошо работает с Ruby (MRI) и JRuby.

На MRI существует глобальный блокировщик виртуальной машины (GVL), который гарантирует, что только один поток может выполнять Ruby-код одновременно. Но если вы выполняете много блокирующего ввода-вывода (например, HTTP-вызовы к внешним API, таким как Twitter), Puma все равно улучшает пропускную способность MRI, позволяя ожиданию ввода-вывода выполняться параллельно. Настоящие параллельные реализации Ruby (TruffleRuby, JRuby) не имеют этой ограничивающей функции.

Быстрый старт

$ gem install puma
$ puma

Без аргументов, puma будет искать файл rackup (.ru) в рабочей директории с именем config.ru.

Поддержка SSL-соединений

Puma будет установлен/скомпилирован с поддержкой SSL-сокетов, предполагая, что файлы разработки OpenSSL установлены на системе.

Если на системе не установлены файлы разработки OpenSSL, Puma будет установлен/скомпилирован, но он не будет поддерживать SSL-соединения.

Фреймворки

Rails

Puma — это по умолчанию используемый сервер для Rails, включенный в сгенерированный Gemfile.

Запустите свой сервер с помощью команды rails:

$ rails server

Многие опции конфигурации и функции Puma недоступны при использовании rails server. Рекомендуется использовать исполняемый файл Puma:``` $ bundle exec puma


### Sinatra

Вы можете запустить свое приложение на Sinatra с помощью Puma из командной строки следующим образом:

$ ruby app.rb -s Puma


Чтобы на самом деле настроить Puma с помощью конфигурационного файла, такого как `puma.rb`, вам нужно использовать исполняемый файл `puma`. Для этого вам необходимо добавить файл rackup в ваше приложение на Sinatra:

```ruby
# config.ru
require './app'
run Sinatra::Application

Затем вы можете запустить свое приложение с помощью:

$ bundle exec puma

Конфигурация

Puma предоставляет множество опций. Чтобы получить полный список опций командной строки, выполните puma -h (или puma --help) или посмотрите Puma::DSL или dsl.rb.

Вы также можете найти несколько примеров конфигурации как часть теста.

Для целей отладки вы можете установить переменную окружения PUMA_LOG_CONFIG со значением, и загруженная конфигурация будет выводиться как часть процесса загрузки.

Пул потоков

Puma использует пул потоков. Вы можете задать минимальное и максимальное количество потоков, доступных в пуле, с помощью флага -t (или --threads):

$ puma -t 8:32
```Puma автоматически масштабирует количество потоков от минимального до максимального в зависимости от наличия трафика. Текущие значения по умолчанию — `0:16` и на MRI — `0:5`. Пожалуйста, экспериментируйте, но будьте осторожны при установке большого числа максимальных потоков, так как это может привести к исчерпанию ресурсов системы (или конкуренции за блокировку глобального VM, при использовании MRI).Обратите внимание, что Puma также создает потоки для внутренних целей (например, обработки медленных клиентов). Поэтому, даже если вы зададите `-t 1:1`, ожидайте создания около 7 потоков в вашем приложении.

### Режим кластера

Puma также предлагает "режим кластера". В режиме кластера Puma создает рабочие процессы от основного процесса. Каждый дочерний процесс все еще имеет свой собственный пул потоков. Вы можете настроить количество рабочих процессов с помощью флага `-w` (или `--workers`):

$ puma -t 8:32 -w 3


Или с использованием переменной окружения `WEB_CONCURRENCY`:

$ WEB_CONCURRENCY=3 puma -t 8:32


Обратите внимание, что потоки всё ещё используются в режиме кластера, и настройка флага потока `-t` задаётся для каждого рабочего процесса, поэтому `-w 2 -t 16:16` запустит всего 32 потока, по 16 в каждом рабочем процессе.

Если переменная окружения `WEB_CONCURRENCY` установлена в значение `"auto"` и библиотека `concurrent-ruby` доступна в вашем приложении, Puma установит количество рабочих процессов в результате [доступных процессоров](https://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent.html#available_processor_count-class_method).

Для подробного обсуждения компромиссов настроек количества потоков и процессов, [см. наши документы](https://github.com/puma/puma/blob/9282a8efa5a0c48e39c60d22ca70051a25df9f55/docs/kubernetes.md#workers-per-pod-and-other-config-issues).В режиме кластера Puma может "предзагрузить" ваше приложение. Это загружает весь код приложения *до* форка. Предзагрузка снижает общее использование памяти вашего приложения за счёт функции операционной системы, называемой [copy-on-write](https://en.wikipedia.org/wiki/Copy-on-write).Если переменная окружения `WEB_CONCURRENCY` установлена в значение > 1 (и флаг `--prune-bundler` не указан), предзагрузка будет включена по умолчанию. В противном случае вы можете использовать флаг `--preload` из командной строки:

$ puma -w 3 --preload


Или, если вы используете файл конфигурации, вы можете использовать метод `preload_app!`:

```ruby
# config/puma.rb
workers 3
preload_app!

Предзагрузка не может использоваться с фазированным перезапуском, так как фазированный перезапуск убивает и перезапускает рабочие процессы по одному, а предзагрузка копирует код мастера в рабочие процессы.

Хуки режима кластера

При использовании режима кластера конфигурационный DSL Puma предоставляет хуки before_fork и on_worker_boot для выполнения кода при форке основного процесса и запуске рабочих процессов соответственно.

Рекомендуется использовать эти хуки с preload_app!, в противном случае константы, загруженные вашим приложением (например, Rails), не будут доступны внутри хуков.

# config/puma.rb
before_fork do
  # Добавьте код для выполнения внутри основного процесса Puma перед форком рабочего процесса.
end

on_worker_boot do
  # Добавьте код для выполнения внутри рабочего процесса Puma после форка.
end

Кроме того, есть on_refork и after_refork хуки, которые используются только в режиме fork_worker, когда рабочий процесс 0 ребёнка форкает внучатого рабочего.```ruby on_refork do

Used only when fork_worker mode is enabled. Add code to be executed inside Puma worker process 0

child before it forks the grandchild worker.

end


```ruby
after_refork do
  # Used only when fork_worker mode is enabled. Add code to be executed inside Puma worker process 0
  # child after it forks the grandchild worker.
end

Важно отметить следующие соображения при форке Ruby ребёнка:

  1. Файловые дескрипторы, такие как сетевые сокеты копируются из родителя в форкнутый дочерний процесс. Двойное использование одного и того же сокета родителем и дочерним процессом приведёт к конфликтам ввода-вывода таких как SocketError, Errno::EPIPE, и EOFError.
  2. Фоновые Ruby потоки, включая потоки, используемые различными сторонними гемами для мониторинга подключений, и т.д., не копируются в дочерний процесс. Часто это не вызывает немедленных проблем, пока стороннее подключение не отключится, после чего не будет надзирателя для переподключения.

Поэтому мы рекомендуем следующее:1. Если это возможно, не устанавливайте никаких сокетных подключений (HTTP, подключения к базе данных и т.д.) внутри основного процесса Puma при загрузке. 2. Если (1) невозможно, используйте before_fork и on_refork для отключения сокетных подключений родителя при форке, чтобы они не были случайно скопированы в дочерний процесс. 3. Используйте on_worker_boot для перезапуска любых фоновых потоков в форкнутом дочернем процессе. 4. Используйте after_refork для перезапуска любых фоновых потоков в родительском процессе.#### Хуки жизненного цикла основного процесса

Конфигурационный DSL Puma предоставляет хуки жизненного цикла основного процесса on_booted, on_restart и on_stopped, которые могут быть использованы для указания блоков кода для выполнения при каждом событии:

# config/puma.rb
on_booted do
  # Добавьте код для выполнения в основном процессе Puma после его загрузки,
  # и также после завершения фазированного перезапуска.
end

on_restart do
  # Добавьте код для выполнения в основном процессе Puma при получении
  # команды перезапуска, но до перезапуска.
end

on_stopped do
  # Добавьте код для выполнения в основном процессе Puma при получении
  # команды остановки, но до завершения.
end

Обработка ошибок

Если Puma обнаруживает ошибку вне контекста вашего приложения, он ответит статусом 400/500 и простым текстовым сообщением об ошибке (см. Puma::Server#lowlevel_error или server.rb). Вы можете указать пользовательское поведение для этой ситуации. Например, вы можете отправить сообщение об ошибке в вашу службу отслеживания ошибок (в этом примере, Rollbar):```ruby lowlevel_error_handler do |e, env, status| if status == 400 message = "Сервер не смог обработать запрос из-за ошибки, такой как неправильно введенный URL, неправильная синтаксическая конструкция или URL, содержащий недопустимые символы.\n" else message = "Произошла ошибка, и инженеры были уведомлены. Пожалуйста, перезагрузите страницу. Если у вас возникли проблемы, свяжитесь с support@example.com\n" Rollbar.critical(e) end end

end

Привязка TCP / сокетов

Привяжите Puma к сокету с помощью флага -b (или --bind):

$ puma -b tcp://127.0.0.1:9292

Чтобы использовать UNIX сокет вместо TCP:

$ puma -b unix:///var/run/puma.sock

Если вам нужно изменить разрешения UNIX сокета, просто добавьте параметр umask:

$ puma -b 'unix:///var/run/puma.sock?umask=0111'

Нужна дополнительная безопасность? Используйте SSL сокеты:

$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert'

Самозаверенные SSL сертификаты (через gem localhost, для использования в разработке):

Puma поддерживает gem localhost для самозаверенных сертификатов. Это особенно полезно, если вы хотите использовать Puma с SSL локально, и самозаверенные сертификаты будут работать для вашего случая. В настоящее время интеграция может использоваться только в MRI.

Puma автоматически настраивает SSL, когда gem localhost загружается в среде development:

Добавьте gem в ваш Gemfile:

group(:development) do
  gem 'localhost'
end

И требуйте его неявно с помощью bundler:

require "bundler"
Bundler.require(:default, ENV["RACK_ENV"].to_sym)

В качестве альтернативы, вы можете требовать gem в вашем файле конфигурации, либо config/puma/development.rb, либо config/puma.rb, либо задать через опцию -C командной строки:

require 'localhost'
# методы конфигурации (из Puma::DSL) по мере необходимости

Кроме того, Puma должен прослушивать SSL сокет:

$ puma -b 'ssl://localhost:9292' -C config/use_local_host.rb
```# Следующие опции позволяют вам получить доступ к Puma через HTTP:
$ puma -b ssl://localhost:9292 -b tcp://localhost:9393 -C config/use_local_host.rb

Управление наборами шифров SSL

Чтобы использовать или избегать конкретных шифров SSL для TLSv1.2 и ниже, используйте опции ssl_cipher_filter или ssl_cipher_list.

Ruby:
$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&ssl_cipher_filter=!aNULL:AES+SHA'
JRuby:
$ puma -b 'ssl://127.0.0.1:9292?keystore=path_to_keystore&keystore-pass=keystore_password&ssl_cipher_list=TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA'

Чтобы настроить доступные TLSv1.3 наборы шифров, используйте опцию ssl_ciphersuites (не доступна для JRuby).

Ruby:
$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&ssl_ciphersuites=TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256'

См. https://www.openssl.org/docs/man1.1.1/man1/ciphers.html для формата фильтра шифров и полного списка наборов шифров.

Отключение TLS v1 с помощью опции no_tlsv1:

$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&no_tlsv1=true'

Управление флагами проверки OpenSSL

Чтобы включить флаги проверки, предлагаемые OpenSSL, используйте опцию verification_flags (не доступна для JRuby):

$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&verification_flags=PARTIAL_CHAIN'

Вы также можете задать несколько флагов проверки (разделяя их запятыми):

$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&verification_flags=PARTIAL_CHAIN,CRL_CHECK'
```Список доступных флагов: `USE_CHECK_TIME`, `CRL_CHECK`, `CRL_CHECK_ALL`, `IGNORE_CRITICAL`, `X509_STRICT`, `ALLOW_PROXY_CERTS`, `POLICY_CHECK`, `EXPLICIT_POLICY`, `INHIBIT_ANY`, `INHIBIT_MAP`, `NOTIFY_POLICY`, `EXTENDED_CRL_SUPPORT`, `USE_DELTAS`, `CHECK_SS_SIGNATURE`, `TRUSTED_FIRST`, `SUITEB_128_LOS_ONLY`, `SUITEB_192_LOS`, `SUITEB_128_LOS`, `PARTIAL_CHAIN`, `NO_ALT_CHAINS`, `NO_CHECK_TIME`
(см. https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_hostflags.html#VERIFICATION-FLAGS).#### Управление расшифровкой пароля OpenSSLДля включения расшифровки в режиме выполнения зашифрованного SSL-ключа (не доступно для JRuby), используйте `key_password_command`:

$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&key_password_command=/path/to/command.sh'


`key_password_command` должен:

1. Быть исполняемым Puma.
2. Выводить пароль расшифровки на stdout.

Пример:

```shell
#!/bin/sh

echo "this is my password"

key_password_command можно использовать с key или key_pem. Если ключ не зашифрован, исполняемый файл не будет запущен.

Сервер управления/статуса

Puma имеет встроенный статусный и управляющий приложения, которые можно использовать для запроса и управления Puma.

$ puma --control-url tcp://127.0.0.1:9293 --control-token foo

Puma запустит сервер управления на локальном хосте на порту 9293. Все запросы к серверу управления должны включать токен управления (в данном случае, token=foo) как параметр запроса. Это позволяет для простой аутентификации. Изучите Puma::App::Status или status.rb, чтобы узнать, какие возможности доступны в статусном приложении.

Вы также можете взаимодействовать с сервером управления через pumactl. Этот командный файл перезапустит Puma:

$ pumactl --control-url 'tcp://127.0.0.1:9293' --control-token foo restart

Чтобы увидеть список опций pumactl, используйте pumactl --help.

Файл конфигурации

Вы также можете предоставить файл конфигурации с помощью флага -C (или --config):``` $ puma -C /path/to/config


Если файл конфигурации не указан, Puma будет искать файл конфигурации по пути `config/puma.rb`. Если указано окружение (через флаг `--environment` или через переменные окружения `APP_ENV`, `RACK_ENV`, или `RAILS_ENV`), Puma будет искать файл конфигурации по пути `config/puma/<environment_name>.rb` и затем будет пытаться использовать `config/puma.rb`.

Если вы хотите предотвратить Puma от поиска файла конфигурации в этих местах, включите флаг `--no-config`:

$ puma --no-config

или

$ puma -C "-"


Другие побочные эффекты установки окружения включают отображение трассировок стека (в `development` или `test`), и установка RACK_ENV может повлиять на промежуточные слои, которые ищут это значение для изменения своего поведения. Значение RACK_ENV по умолчанию для Puma — `development`. Вы можете увидеть все значения по умолчанию конфигурации в `Puma::Configuration#puma_default_options` или [configuration.rb](https://github.com/puma/puma/blob/61c6213fbab/lib/puma/configuration.rb#L182-L204). Просмотрите `Puma::DSL` или [dsl.rb](https://github.com/puma/puma/blob/master/lib/puma/dsl.rb), чтобы узнать о всех доступных опциях.

## Перезапуск

Puma включает возможность перезапуска себя. Когда это возможно (MRI, Rubinius, JRuby), Puma выполняет "горячий перезапуск". Это та же функциональность, доступная в *Unicorn* и *NGINX*, которые сохраняют серверные сокеты открытыми между перезапусками. Это гарантирует, что нет отброшенных ожидающих запросов во время перезапуска.Для получения дополнительной информации см. документацию по [перезапуску](docs/restart.md).

## Сигналы

Puma отвечает на несколько сигналов. Подробное руководство по использованию UNIX сигналов с Puma можно найти в документации по [сигналам](docs/signals.md).

## Ограничения платформ

Некоторые платформы не поддерживают все функции Puma.

  * **JRuby**, **Windows**: серверные сокеты не являются бесшовными при перезапуске, они должны быть закрыты и заново открыты. Эти платформы не имеют способа передачи дескрипторов в новый процесс, доступный Ruby. Также режим кластера не поддерживается из-за отсутствия fork(2).
  * **Windows**: режим кластера не поддерживается из-за отсутствия fork(2).
  * **Kubernetes**: Способ, которым Kubernetes управляет завершением работы падов, плохо взаимодействует с серверными процессами, реализующими грациозное завершение работы, такими как Puma. Подробнее см. раздел [Kubernetes](docs/kubernetes.md) документации.

## Знаменитые ошибки

Для версий MRI 2.2.7, 2.2.8, 2.2.9, 2.2.10, 2.3.4 и 2.4.1 вы можете увидеть ```поток закрыт в другой поток (IOError)```. Это может быть вызвано [ошибкой Ruby](https://bugs.ruby-lang.org/issues/13632). Это можно исправить с помощью гема https://rubygems.org/gems/stopgap_13632:

```ruby
if %w(2.2.7 2.2.8 2.2.9 2.2.10 2.3.4 2.4.1).include? RUBY_VERSION
  begin
    require 'stopgap_13632'
  rescue LoadError
  end
end

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

  • Puma поддерживает Capistrano с помощью внешнего гема. * Кроме того, Puma поддерживает встроенное демонизирование с помощью гема puma-daemon. Гем восстанавливает опцию daemonize, которая была удалена из Puma начиная с версии 5, но только для MRI Ruby.

Использование процессных мониторов с Puma является распространённой практикой. Современные процессные мониторы, такие как systemd или rc.d, предоставляют непрерывное мониторинг и перезапуски для повышения надёжности в производственной среде:

Командные руководства:

Расширения сообщества

Плагины

  • puma-metrics — экспортирует метрики Puma в Prometheus

  • puma-plugin-statsd — отправляет метрики Puma в statsd

  • puma-plugin-systemd — более глубокая интеграция с systemd для уведомлений, статуса и вордога. В Puma 5.1.0 была интегрирована поддержка уведомлений и вордога, что, вероятно, конфликтует с этим плагином. В Puma 6.1.0 была добавлена поддержка статуса, что полностью устаревает этот плагин.

  • puma-plugin-telemetry — плагин для сбора телеметрии Puma, предлагающий различные цели для публикации

  • puma-acme — автоматическое развертывание и настройка сертификатов SSL/HTTPS### Мониторинг

  • puma-status — мониторинг CPU/Mem/Load запущенных экземпляров Puma из командной строки

Вклад

Подробности о вкладе содержатся в руководстве по вкладу.

Лицензия

Puma защищена авторским правом Evan Phoenix и вкладчиков, лицензирована под лицензией BSD 3-Клause. Подробности содержатся в включённом файле LICENSE.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/mirrors-Puma_old1.git
git@api.gitlife.ru:oschina-mirror/mirrors-Puma_old1.git
oschina-mirror
mirrors-Puma_old1
mirrors-Puma_old1
master