From ef841b6704bae4e82f6f8b3ec59d4c37565ddb76 Mon Sep 17 00:00:00 2001 From: Erno Kuvaja Date: Mon, 12 Feb 2018 16:58:03 +0000 Subject: [PATCH] Limit default workers to 8 With modern servers it's not uncommon to see environments that has dozens of logical processors. Glance defaults workers to number of these logical processors seen by OS and each worker spins up pool of 1000 threads. Having dozens of these thread pools consuming resources is total overkill for most of the environments. This change limits the amount of workers used by default to 8 which should be plenty for most of the deployments. This limitation does not affect if more workers is specifically configured in the config file. Change-Id: I6fcf2f8a416e34c0c719e1abd73f0525e686be5e Closes-Bug: #1748916 (cherry picked from commit 6f87c7d567c9006b139b01fd1ab3bb9420fb407d) --- glance/common/wsgi.py | 11 ++++++++--- glance/tests/unit/common/test_wsgi.py | 22 ++++++++++++++++++++-- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/glance/common/wsgi.py b/glance/common/wsgi.py index a94576b80d..13785f2097 100644 --- a/glance/common/wsgi.py +++ b/glance/common/wsgi.py @@ -207,7 +207,10 @@ Number of Glance worker processes to start. Provide a non-negative integer value to set the number of child process workers to service requests. By default, the number of CPUs -available is set as the value for ``workers``. +available is set as the value for ``workers`` limited to 8. For +example if the processor count is 6, 6 workers will be used, if the +processor count is 24 only 8 workers will be used. The limit will only +apply to the default value, if 24 workers is configured, 24 is used. Each worker process is made to listen on the port set in the configuration file and contains a greenthread pool of size 1000. @@ -332,8 +335,10 @@ except ImportError: def get_num_workers(): """Return the configured number of workers.""" if CONF.workers is None: - # None implies the number of CPUs - return processutils.get_worker_count() + # None implies the number of CPUs limited to 8 + # See Launchpad bug #1748916 and the config help text + workers = processutils.get_worker_count() + return workers if workers < 8 else 8 return CONF.workers diff --git a/glance/tests/unit/common/test_wsgi.py b/glance/tests/unit/common/test_wsgi.py index 0f4c5ad566..710d94807e 100644 --- a/glance/tests/unit/common/test_wsgi.py +++ b/glance/tests/unit/common/test_wsgi.py @@ -604,7 +604,7 @@ class ServerTest(test_utils.BaseTestCase): socket_timeout=900) def test_number_of_workers(self): - """Ensure the default number of workers matches num cpus.""" + """Ensure the number of workers matches num cpus limited to 8.""" def pid(): i = 1 while True: @@ -612,12 +612,30 @@ class ServerTest(test_utils.BaseTestCase): yield i with mock.patch.object(os, 'fork') as mock_fork: + with mock.patch('oslo_concurrency.processutils.get_worker_count', + return_value=4): + mock_fork.side_effect = pid + server = wsgi.Server() + server.configure = mock.Mock() + fake_application = "fake-application" + server.start(fake_application, None) + self.assertEqual(4, len(server.children)) + with mock.patch('oslo_concurrency.processutils.get_worker_count', + return_value=24): + mock_fork.side_effect = pid + server = wsgi.Server() + server.configure = mock.Mock() + fake_application = "fake-application" + server.start(fake_application, None) + self.assertEqual(8, len(server.children)) mock_fork.side_effect = pid server = wsgi.Server() server.configure = mock.Mock() fake_application = "fake-application" server.start(fake_application, None) - self.assertEqual(processutils.get_worker_count(), + cpus = processutils.get_worker_count() + expected_workers = cpus if cpus < 8 else 8 + self.assertEqual(expected_workers, len(server.children))