1
0
Fork 0
mirror of https://github.com/puma/puma.git synced 2022-11-09 13:48:40 -05:00

Print warning when running one-worker cluster (#2565)

* Print warning when running one-worker cluster

Running Puma in cluster-mode is likely a misconfiguration in most
scenarios.

Cluster mode has some overhead of running an addtional 'control' process
in order to manage the cluster. If only running a single worker it is
likely not worth paying that overhead vs running in single mode with
additional threads instead.

There are some scenarios where running cluster mode with a single worker
may still be warranted and valid under certain deployment scenarios, see
the linked issue for details.

From experience at work, we were able to migrate our Rails applications
from single worker cluster to single-mode and saw a reduction of RAM
usage of around ~15%.

Closes #2534

* Remove link to issue

* Add #silence_single_worker_warning option

* Test single_worker_warning
This commit is contained in:
Christian Gregg 2021-03-09 14:40:31 +00:00 committed by GitHub
parent ae6a506029
commit 81d26e91b7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 58 additions and 0 deletions

View file

@ -2,6 +2,7 @@
* Features * Features
* Your feature goes here <Most recent on the top, like GitHub> (#Github Number) * Your feature goes here <Most recent on the top, like GitHub> (#Github Number)
* Warn when running Cluster mode with a single worker (#2565)
* Bugfixes * Bugfixes
* Your bugfix goes here <Most recent on the top, like GitHub> (#Github Number) * Your bugfix goes here <Most recent on the top, like GitHub> (#Github Number)

View file

@ -382,6 +382,8 @@ module Puma
log "Use Ctrl-C to stop" log "Use Ctrl-C to stop"
single_worker_warning
redirect_io redirect_io
Plugins.fire_background Plugins.fire_background
@ -470,6 +472,15 @@ module Puma
private private
def single_worker_warning
return if @options[:workers] != 1 || @options[:silence_single_worker_warning]
log "! WARNING: Detected running cluster mode with 1 worker."
log "! Running Puma in cluster mode with a single worker is often a misconfiguration."
log "! Consider running Puma in single-mode in order to reduce memory overhead."
log "! Set the `silence_single_worker_warning` option to silence this warning message."
end
# loops thru @workers, removing workers that exited, and calling # loops thru @workers, removing workers that exited, and calling
# `#term` if needed # `#term` if needed
def wait_workers def wait_workers

View file

@ -193,6 +193,7 @@ module Puma
:debug => false, :debug => false,
:binds => ["tcp://#{DefaultTCPHost}:#{DefaultTCPPort}"], :binds => ["tcp://#{DefaultTCPHost}:#{DefaultTCPPort}"],
:workers => Integer(ENV['WEB_CONCURRENCY'] || 0), :workers => Integer(ENV['WEB_CONCURRENCY'] || 0),
:silence_single_worker_warning => false,
:mode => :http, :mode => :http,
:worker_timeout => DefaultWorkerTimeout, :worker_timeout => DefaultWorkerTimeout,
:worker_boot_timeout => DefaultWorkerTimeout, :worker_boot_timeout => DefaultWorkerTimeout,

View file

@ -482,6 +482,13 @@ module Puma
@options[:workers] = count.to_i @options[:workers] = count.to_i
end end
# Disable warning message when running in cluster mode with a single worker.
#
# @note Cluster mode only.
def silence_single_worker_warning
@options[:silence_single_worker_warning] = true
end
# Code to run immediately before master process # Code to run immediately before master process
# forks workers (once on boot). These hooks can block if necessary # forks workers (once on boot). These hooks can block if necessary
# to wait for background operations unknown to Puma to finish before # to wait for background operations unknown to Puma to finish before

View file

@ -342,6 +342,22 @@ class TestConfigFile < TestConfigFileBase
assert_equal 2, conf.final_options[:max_threads] assert_equal 2, conf.final_options[:max_threads]
end end
def test_silence_single_worker_warning_default
conf = Puma::Configuration.new
conf.load
assert_equal false, conf.options[:silence_single_worker_warning]
end
def test_silence_single_worker_warning_overwrite
conf = Puma::Configuration.new do |c|
c.silence_single_worker_warning
end
conf.load
assert_equal true, conf.options[:silence_single_worker_warning]
end
private private
def assert_run_hooks(hook_name, options = {}) def assert_run_hooks(hook_name, options = {})

View file

@ -313,6 +313,28 @@ RUBY
assert_equal 0, worker_load_count assert_equal 0, worker_load_count
end end
def test_warning_message_outputted_when_single_worker
cli_server "-w 1 test/rackup/hello.ru"
output = []
while (line = @server.gets) && line !~ /Worker \d \(PID/
output << line
end
assert_match /WARNING: Detected running cluster mode with 1 worker/, output.join
end
def test_warning_message_not_outputted_when_single_worker_silenced
cli_server "-w 1 test/rackup/hello.ru", config: "silence_single_worker_warning"
output = []
while (line = @server.gets) && line !~ /Worker \d \(PID/
output << line
end
refute_match /WARNING: Detected running cluster mode with 1 worker/, output.join
end
private private
def worker_timeout(timeout, iterations, config) def worker_timeout(timeout, iterations, config)