Puma는 Ruby/Rack 애플리케이션을 위한 간단하고 빠른 다중 스레드 및 고도로 병렬인 HTTP 1.1 서버 입니다.
Puma는 Ruby로 작성된 Rack 기반 HTTP 애플리케이션용 서버입니다. 그것은:
원래 Rubinius용 서버로 설계된 Puma는 Ruby(MRI) 및 JRuby와도 잘 작동합니다.
MRI에는 한 번에 하나의 스레드만 Ruby 코드를 실행할 수 있도록 보장하는 GVL(전역 VM 잠금)이 있습니다. 그러나 차단 IO(예: Twitter와 같은 외부 API에 대한 HTTP 호출)를 많이 수행하는 경우 Puma는 IO 대기가 병렬로 수행되도록 허용하여 MRI의 처리량을 향상시킵니다. 진정한 병렬 Ruby 구현(TruffleRuby, JRuby)에는 이러한 제한이 없습니다.
$ gem install puma
$ puma
인수가 없으면 puma는 config.ru
라는 작업 디렉터리에서 랙업(.ru) 파일을 찾습니다.
Puma는 OpenSSL 개발 파일이 시스템에 설치되어 있다고 가정하고 SSL 소켓을 지원하여 설치/컴파일합니다.
시스템에 OpenSSL 개발 파일이 설치되지 않은 경우 Puma는 설치/컴파일하지만 SSL 연결을 허용하지 않습니다.
Puma는 생성된 Gemfile에 포함된 Rails의 기본 서버입니다.
rails
명령을 사용하여 서버를 시작하십시오.
$ rails server
rails server
사용할 때는 많은 구성 옵션과 Puma 기능을 사용할 수 없습니다. 대신 Puma의 실행 파일을 사용하는 것이 좋습니다.
$ bundle exec puma
다음과 같이 명령줄에서 Puma로 Sinatra 애플리케이션을 실행할 수 있습니다.
$ ruby app.rb -s Puma
그러나 puma.rb
와 같은 구성 파일을 사용하여 실제로 Puma를 구성하려면 puma
실행 파일을 사용해야 합니다. 이렇게 하려면 Sinatra 앱에 랙업 파일을 추가해야 합니다.
# config.ru
require './app'
run Sinatra :: Application
그런 다음 다음을 사용하여 애플리케이션을 시작할 수 있습니다.
$ bundle exec puma
푸마는 다양한 옵션을 제공합니다. CLI 옵션의 전체 목록을 보려면 puma -h
(또는 puma --help
)를 참조하거나 Puma::DSL
또는 dsl.rb를 참조하십시오.
테스트 모음의 일부로 여러 구성 예를 찾을 수도 있습니다.
디버깅 목적으로 환경 변수 PUMA_LOG_CONFIG
에 값을 설정할 수 있으며 로드된 구성은 부팅 프로세스의 일부로 인쇄됩니다.
Puma는 스레드 풀을 사용합니다. -t
(또는 --threads
) 플래그를 사용하여 풀에서 사용 가능한 최소 및 최대 스레드 수를 설정할 수 있습니다.
$ puma -t 8:32
Puma는 트래픽 양에 따라 최소 스레드 수부터 최대 스레드 수까지 자동으로 확장합니다. 현재 기본값은 0:16
이고 MRI에서는 0:5
입니다. 마음껏 실험해 보세요. 하지만 최대 스레드 수를 큰 숫자로 설정하지 않도록 주의하십시오. 시스템의 리소스가 고갈될 수 있습니다(또는 MRI를 사용할 때 전역 VM 잠금에 대한 경합이 발생할 수 있습니다).
또한 Puma는 내부 목적(예: 느린 클라이언트 처리)을 위해 자체적으로 스레드를 생성한다는 점에 유의하세요. 따라서 -t 1:1을 지정하더라도 애플리케이션에 약 7개의 스레드가 생성될 것으로 예상됩니다.
Puma는 "클러스터 모드"도 제공합니다. 클러스터 모드 fork
마스터 프로세스의 작업자입니다. 각 하위 프로세스에는 여전히 자체 스레드 풀이 있습니다. -w
(또는 --workers
) 플래그를 사용하여 작업자 수를 조정할 수 있습니다.
$ puma -t 8:32 -w 3
또는 WEB_CONCURRENCY
환경 변수를 사용하면 다음과 같습니다.
$ WEB_CONCURRENCY=3 puma -t 8:32
스레드는 여전히 클러스터 모드에서 사용되며 -t
스레드 플래그 설정은 작업자별로 이루어지므로 -w 2 -t 16:16
각 작업자 프로세스에 16개씩 총 32개의 스레드를 생성합니다.
WEB_CONCURRENCY
환경 변수가 "auto"
로 설정되어 있고 애플리케이션에서 concurrent-ruby
gem을 사용할 수 있는 경우 Puma는 작업자 프로세스 수를 사용 가능한 프로세서의 결과로 설정합니다.
스레드 및 프로세스 수 설정의 장단점에 대한 심층적인 논의는 문서를 참조하세요.
클러스터 모드에서 Puma는 애플리케이션을 "미리 로드"할 수 있습니다. 이렇게 하면 분기하기 전에 모든 애플리케이션 코드가 로드됩니다. 미리 로드하면 쓰기 중 복사라는 운영 체제 기능을 통해 애플리케이션의 총 메모리 사용량이 줄어듭니다.
WEB_CONCURRENCY
환경 변수가 1보다 큰 값으로 설정되고 --prune-bundler
지정되지 않은 경우 기본적으로 사전 로드가 활성화됩니다. 그렇지 않으면 명령줄에서 --preload
플래그를 사용할 수 있습니다.
$ puma -w 3 --preload
또는 구성 파일을 사용하는 경우 preload_app!
방법:
# config/puma.rb
workers 3
preload_app!
단계적 다시 시작은 작업자를 하나씩 종료하고 다시 시작하며 사전 로드는 마스터 코드를 작업자에 복사하므로 사전 로드는 단계적 다시 시작과 함께 사용할 수 없습니다.
클러스터 모드를 사용할 때 Puma의 구성 DSL은 마스터 프로세스 포크와 하위 작업자가 각각 부팅될 때 코드를 실행하기 위해 before_fork
및 on_worker_boot
후크를 제공합니다.
preload_app!
, 그렇지 않으면 애플리케이션에서 로드한 상수(예: Rails
)를 후크 내에서 사용할 수 없습니다.
# config/puma.rb
before_fork do
# Add code to run inside the Puma master process before it forks a worker child.
end
on_worker_boot do
# Add code to run inside the Puma worker process after forking.
end
또한 작업자 0 하위 프로세스가 손자 작업자를 분기할 때 fork_worker
모드에서만 사용되는 on_refork
후크가 있습니다.
on_refork do
# Used only when fork_worker mode is enabled. Add code to run inside the Puma worker 0
# child process before it forks a grandchild worker.
end
중요한 것은 Ruby가 하위 프로세스를 포크할 때 다음 고려 사항에 유의하세요.
SocketError
, Errno::EPIPE
및 EOFError
와 같은 I/O 충돌이 발생합니다.따라서 다음을 권장합니다.
before_fork
및 on_refork
사용하여 분기 시 상위 소켓 연결을 끊습니다. 그러면 실수로 하위 프로세스에 복사되지 않습니다.on_worker_boot
사용하여 분기된 하위 항목의 백그라운드 스레드를 다시 시작하세요. Puma의 구성 DSL은 각 이벤트에서 실행할 코드 블록을 지정하는 데 사용할 수 있는 마스터 프로세스 수명 주기 후크 on_booted
, on_restart
및 on_stopped
제공합니다.
# config/puma.rb
on_booted do
# Add code to run in the Puma master process after it boots,
# and also after a phased restart completes.
end
on_restart do
# Add code to run in the Puma master process when it receives
# a restart command but before it restarts.
end
on_stopped do
# Add code to run in the Puma master process when it receives
# a stop command but before it shuts down.
end
Puma가 애플리케이션 컨텍스트 외부에서 오류를 발견하면 400/500 및 간단한 텍스트 오류 메시지로 응답합니다( Puma::Server#lowlevel_error
또는 server.rb 참조). 이 시나리오에 대한 사용자 정의 동작을 지정할 수 있습니다. 예를 들어 타사 오류 추적 서비스(이 예에서는 롤바)에 오류를 보고할 수 있습니다.
lowlevel_error_handler do | e , env , status |
if status == 400
message = "The server could not process the request due to an error, such as an incorrectly typed URL, malformed syntax, or a URL that contains illegal characters. n "
else
message = "An error has occurred, and engineers have been informed. Please reload the page. If you continue to have problems, contact [email protected] n "
Rollbar . critical ( e )
end
[ status , { } , [ message ] ]
end
-b
(또는 --bind
) 플래그를 사용하여 Puma를 소켓에 바인딩합니다.
$ puma -b tcp://127.0.0.1:9292
TCP 대신 UNIX 소켓을 사용하려면:
$ 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'
localhost
gem을 통해): Puma는 자체 서명된 인증서에 대해 localhost
gem을 지원합니다. 이는 로컬에서 SSL과 함께 Puma를 사용하려는 경우 특히 유용하며 자체 서명된 인증서가 사용 사례에 적합합니다. 현재 통합은 MRI에서만 사용할 수 있습니다.
Puma는 localhost
gem이 development
환경에 로드될 때 자동으로 SSL을 구성합니다.
Gemfile에 보석을 추가합니다:
group ( :development ) do
gem 'localhost'
end
번들러를 사용하여 암시적으로 요구합니다.
require "bundler"
Bundler . require ( :default , ENV [ "RACK_ENV" ] . to_sym )
또는 구성 파일( config/puma/development.rb
, config/puma.rb
)에서 gem을 요구하거나 -C
cli 옵션을 통해 설정할 수 있습니다:
require 'localhost'
# configuration methods (from Puma::DSL) as needed
또한 Puma는 SSL 소켓을 수신해야 합니다.
$ puma -b ' ssl://localhost:9292 ' -C config/use_local_host.rb
# The following options allow you to reach Puma over HTTP as well:
$ puma -b ssl://localhost:9292 -b tcp://localhost:9393 -C config/use_local_host.rb
TLSv1.2 이하에 대한 특정 SSL 암호를 사용하거나 방지하려면 ssl_cipher_filter
또는 ssl_cipher_list
옵션을 사용하세요.
$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&ssl_cipher_filter=!aNULL:AES+SHA'
$ 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에서는 사용할 수 없음).
$ 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을 참조하세요.
no_tlsv1
옵션을 사용하여 TLS v1을 비활성화합니다.
$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&no_tlsv1=true'
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).
암호화된 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
다음을 충족해야 합니다.
예를 들어:
#! /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는 localhost 포트 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
# or
$ puma -C "-"
환경 설정의 다른 부작용은 스택 추적을 표시할지 여부( development
또는 test
중)이며, RACK_ENV를 설정하면 동작을 변경하기 위해 이 값을 찾는 미들웨어에 잠재적으로 영향을 미칠 수 있습니다. 기본 puma RACK_ENV 값은 development
입니다. Puma::Configuration#puma_default_options
또는 Configuration.rb에서 모든 구성 기본값을 볼 수 있습니다.
사용 가능한 모든 옵션을 보려면 Puma::DSL
또는 dsl.rb를 확인하세요.
Puma에는 스스로 다시 시작하는 기능이 포함되어 있습니다. 사용 가능한 경우(MRI, Rubinius, JRuby) Puma는 "핫 재시작"을 수행합니다. 이는 다시 시작하는 동안 서버 소켓을 열어 두는 Unicorn 및 NGINX 에서 사용할 수 있는 것과 동일한 기능입니다. 이렇게 하면 다시 시작하는 동안 보류 중인 요청이 삭제되지 않습니다.
자세한 내용은 다시 시작 설명서를 참조하세요.
푸마는 여러 신호에 반응합니다. Puma에서 UNIX 신호를 사용하는 방법에 대한 자세한 지침은 신호 문서에서 찾을 수 있습니다.
일부 플랫폼은 모든 Puma 기능을 지원하지 않습니다.
MRI 버전 2.2.7, 2.2.8, 2.2.9, 2.2.10, 2.3.4 및 2.4.1의 경우 stream closed in another thread (IOError)
. Ruby 버그로 인해 발생할 수 있습니다. 보석 https://rubygems.org/gems/stopgap_13632로 수정할 수 있습니다.
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 Ruby gem을 통해 내장된 데몬화를 지원합니다. 이 보석은 Puma 버전 5부터 제거된 daemonize
옵션을 복원하지만 MRI Ruby에만 해당됩니다.
Puma에서는 프로세스 모니터를 사용하는 것이 일반적입니다. systemd 또는 rc.d와 같은 최신 프로세스 모니터는 생산 환경의 안정성 향상을 위해 지속적인 모니터링 및 재시작 기능을 제공합니다.
커뮤니티 가이드:
기여 가이드에서 기여에 대한 자세한 내용을 확인하세요.
Puma는 BSD 3-Clause 라이센스에 따라 라이센스가 부여된 Evan Phoenix의 저작권 및 기여자입니다. 자세한 내용은 포함된 LICENSE 파일을 참조하세요.