From 079ce2b292e9e5651234ea74c068ff728419464e Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Mon, 12 Aug 2024 22:56:16 +0100 Subject: [PATCH] router: Make the number of router threads configurable Unit generally creates an extra number of router threads (to handle client connections, not incl the main thread) to match the number of available CPUs. There are cases when this can go wrong, e.g on a high CPU count machine and Unit is being effectively limited to a few CPUs via the cgroups cpu controller. So Unit may create a large number of router threads when they are only going to effectively run on a couple of CPUs or so. There may be other cases where you would like to tweak the number of router threads, depending on your workload. As it turns out it looks like it was intended to be made configurable but was just never hooked up to the config system. This adds a new '/settings/router/threads' config option which can be set like { "listen": { ... }, "settings": { "router": { "threads": 2 } }, ... } Before this patch (on a four cpu system) $ ps -efL | grep router andrew 419832 419829 419832 0 5 Aug12 pts/10 00:00:00 unit: router andrew 419832 419829 419833 0 5 Aug12 pts/10 00:00:00 unit: router andrew 419832 419829 419834 0 5 Aug12 pts/10 00:00:00 unit: router andrew 419832 419829 445145 0 5 03:31 pts/10 00:00:00 unit: router andrew 419832 419829 445146 0 5 03:31 pts/10 00:00:00 unit: router After, with a threads setting of 2. $ ps -efL | grep router andrew 419832 419829 419832 0 3 Aug12 pts/10 00:00:00 unit: router andrew 419832 419829 419833 0 3 Aug12 pts/10 00:00:00 unit: router andrew 419832 419829 419834 0 3 Aug12 pts/10 00:00:00 unit: router Closes: https://github.com/nginx/unit/issues/1042 Signed-off-by: Andrew Clayton --- src/nxt_conf_validation.c | 17 +++++++++++++++++ src/nxt_router.c | 18 +++++++++++------- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index 04091745c..477bf7cce 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -240,6 +240,7 @@ static nxt_int_t nxt_conf_vldt_js_module_element(nxt_conf_validation_t *vldt, static nxt_conf_vldt_object_t nxt_conf_vldt_setting_members[]; static nxt_conf_vldt_object_t nxt_conf_vldt_http_members[]; +static nxt_conf_vldt_object_t nxt_conf_vldt_router_members[]; static nxt_conf_vldt_object_t nxt_conf_vldt_websocket_members[]; static nxt_conf_vldt_object_t nxt_conf_vldt_static_members[]; static nxt_conf_vldt_object_t nxt_conf_vldt_forwarded_members[]; @@ -309,6 +310,11 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_setting_members[] = { .type = NXT_CONF_VLDT_OBJECT, .validator = nxt_conf_vldt_object, .u.members = nxt_conf_vldt_http_members, + }, { + .name = nxt_string("router"), + .type = NXT_CONF_VLDT_OBJECT, + .validator = nxt_conf_vldt_object, + .u.members = nxt_conf_vldt_router_members, #if (NXT_HAVE_NJS) }, { .name = nxt_string("js_module"), @@ -377,6 +383,17 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_http_members[] = { }; +static nxt_conf_vldt_object_t nxt_conf_vldt_router_members[] = { + { + .name = nxt_string("threads"), + .type = NXT_CONF_VLDT_INTEGER, + .validator = nxt_conf_vldt_threads, + }, + + NXT_CONF_VLDT_END +}; + + static nxt_conf_vldt_object_t nxt_conf_vldt_websocket_members[] = { { .name = nxt_string("read_timeout"), diff --git a/src/nxt_router.c b/src/nxt_router.c index 432094511..2fa1c4143 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -1412,7 +1412,7 @@ nxt_router_conf_send(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, static nxt_conf_map_t nxt_router_conf[] = { { - nxt_string("listeners_threads"), + nxt_string("threads"), NXT_CONF_MAP_INT32, offsetof(nxt_router_conf_t, threads), }, @@ -1630,7 +1630,7 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *js_module; #endif nxt_conf_value_t *root, *conf, *http, *value, *websocket; - nxt_conf_value_t *applications, *application; + nxt_conf_value_t *applications, *application, *router_conf; nxt_conf_value_t *listeners, *listener; nxt_socket_conf_t *skcf; nxt_router_conf_t *rtcf; @@ -1640,6 +1640,7 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_router_app_conf_t apcf; nxt_router_listener_conf_t lscf; + static const nxt_str_t router_path = nxt_string("/settings/router"); static const nxt_str_t http_path = nxt_string("/settings/http"); static const nxt_str_t applications_path = nxt_string("/applications"); static const nxt_str_t listeners_path = nxt_string("/listeners"); @@ -1673,11 +1674,14 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, rtcf = tmcf->router_conf; mp = rtcf->mem_pool; - ret = nxt_conf_map_object(mp, root, nxt_router_conf, - nxt_nitems(nxt_router_conf), rtcf); - if (ret != NXT_OK) { - nxt_alert(task, "root map error"); - return NXT_ERROR; + router_conf = nxt_conf_get_path(root, &router_path); + if (router_conf != NULL) { + ret = nxt_conf_map_object(mp, router_conf, nxt_router_conf, + nxt_nitems(nxt_router_conf), rtcf); + if (ret != NXT_OK) { + nxt_alert(task, "router_conf map error"); + return NXT_ERROR; + } } if (rtcf->threads == 0) {