Skip to content

Commit

Permalink
conf, router: Make the listen(2) backlog configurable
Browse files Browse the repository at this point in the history
@oopsoop2 on GitHub reported a performance issue related to the default
listen(2) backlog size of 511 on nginx. They found that increasing it
helped, nginx has a config option to configure this.

They would like to be able to do the same on Unit (which also defaults
to 511 on some systems, incl Linux). This seems reasonable.

This adds a new per-listener 'backlog' config option, e.g

  {
      "listeners": {
          "[::1]:8080": {
              "pass": "routes",
              "backlog": 1024
          },
      }

      ...
  }

This doesn't effect the control socket.

Closes: #1384
Reported-by: <https://github.com/oopsoop2>
Signed-off-by: Andrew Clayton <[email protected]>
  • Loading branch information
ac000 committed Aug 15, 2024
1 parent 2022427 commit fbf15bd
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 30 deletions.
32 changes: 32 additions & 0 deletions src/nxt_conf_validation.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ static nxt_int_t nxt_conf_vldt_app_name(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value, void *data);
static nxt_int_t nxt_conf_vldt_forwarded(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value, void *data);
static nxt_int_t nxt_conf_vldt_listen_backlog(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value, void *data);
static nxt_int_t nxt_conf_vldt_app(nxt_conf_validation_t *vldt,
nxt_str_t *name, nxt_conf_value_t *value);
static nxt_int_t nxt_conf_vldt_object(nxt_conf_validation_t *vldt,
Expand Down Expand Up @@ -424,6 +426,10 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_listener_members[] = {
.type = NXT_CONF_VLDT_OBJECT,
.validator = nxt_conf_vldt_object,
.u.members = nxt_conf_vldt_client_ip_members
}, {
.name = nxt_string("backlog"),
.type = NXT_CONF_VLDT_NUMBER,
.validator = nxt_conf_vldt_listen_backlog,
},

#if (NXT_TLS)
Expand Down Expand Up @@ -2677,6 +2683,32 @@ nxt_conf_vldt_forwarded(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
}


static nxt_int_t
nxt_conf_vldt_listen_backlog(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value, void *data)
{
int64_t backlog;

backlog = nxt_conf_get_number(value);

/*
* POSIX allows this to be 0 and some systems use -1 to
* indicate to use the OS's default value.
*/
if (backlog < -1) {
return nxt_conf_vldt_error(vldt, "The \"backlog\" number must be "
"equal to or greater than -1.");
}

if (backlog > NXT_INT32_T_MAX) {
return nxt_conf_vldt_error(vldt, "The \"backlog\" number must "
"not exceed %d.", NXT_INT32_T_MAX);
}

return NXT_OK;
}


static nxt_int_t
nxt_conf_vldt_app(nxt_conf_validation_t *vldt, nxt_str_t *name,
nxt_conf_value_t *value)
Expand Down
44 changes: 26 additions & 18 deletions src/nxt_router.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,6 @@ typedef struct {
} nxt_router_app_conf_t;


typedef struct {
nxt_str_t pass;
nxt_str_t application;
} nxt_router_listener_conf_t;


#if (NXT_TLS)

Expand Down Expand Up @@ -1494,6 +1489,12 @@ static nxt_conf_map_t nxt_router_listener_conf[] = {
NXT_CONF_MAP_STR_COPY,
offsetof(nxt_router_listener_conf_t, application),
},

{
nxt_string("backlog"),
NXT_CONF_MAP_INT32,
offsetof(nxt_router_listener_conf_t, backlog),
},
};


Expand Down Expand Up @@ -1964,13 +1965,10 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
break;
}

skcf = nxt_router_socket_conf(task, tmcf, &name);
if (skcf == NULL) {
goto fail;
}

nxt_memzero(&lscf, sizeof(lscf));

lscf.backlog = -1;

ret = nxt_conf_map_object(mp, listener, nxt_router_listener_conf,
nxt_nitems(nxt_router_listener_conf),
&lscf);
Expand All @@ -1981,6 +1979,13 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,

nxt_debug(task, "application: %V", &lscf.application);

tmcf->listener_conf = &lscf;

skcf = nxt_router_socket_conf(task, tmcf, &name);
if (skcf == NULL) {
goto fail;
}

// STUB, default values if http block is not defined.
skcf->header_buffer_size = 2048;
skcf->large_header_buffer_size = 8192;
Expand Down Expand Up @@ -2686,12 +2691,13 @@ static nxt_socket_conf_t *
nxt_router_socket_conf(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
nxt_str_t *name)
{
size_t size;
nxt_int_t ret;
nxt_bool_t wildcard;
nxt_sockaddr_t *sa;
nxt_socket_conf_t *skcf;
nxt_listen_socket_t *ls;
size_t size;
nxt_int_t ret;
nxt_bool_t wildcard;
nxt_sockaddr_t *sa;
nxt_socket_conf_t *skcf;
nxt_listen_socket_t *ls;
nxt_router_listener_conf_t *lscf;

sa = nxt_sockaddr_parse(tmcf->mem_pool, name);
if (nxt_slow_path(sa == NULL)) {
Expand Down Expand Up @@ -2727,8 +2733,10 @@ nxt_router_socket_conf(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,

nxt_listen_socket_remote_size(ls);

lscf = tmcf->listener_conf;

ls->socket = -1;
ls->backlog = NXT_LISTEN_BACKLOG;
ls->backlog = lscf->backlog > -1 ? lscf->backlog : NXT_LISTEN_BACKLOG;
ls->flags = NXT_NONBLOCK;
ls->read_after_accept = 1;
}
Expand Down Expand Up @@ -2875,7 +2883,7 @@ nxt_router_listen_socket_ready(nxt_task_t *task, nxt_port_recv_msg_t *msg,

nxt_socket_defer_accept(task, s, rpc->socket_conf->listen->sockaddr);

ret = nxt_listen_socket(task, s, NXT_LISTEN_BACKLOG);
ret = nxt_listen_socket(task, s, rpc->socket_conf->listen->backlog);
if (nxt_slow_path(ret != NXT_OK)) {
goto fail;
}
Expand Down
30 changes: 18 additions & 12 deletions src/nxt_router.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,28 +70,34 @@ typedef struct {
} action;
} nxt_router_engine_conf_t;

typedef struct {
nxt_str_t pass;
nxt_str_t application;
int backlog;
} nxt_router_listener_conf_t;

typedef struct {
#if (NXT_TLS)
nxt_queue_t tls; /* of nxt_router_tlssock_t */
nxt_queue_t tls; /* of nxt_router_tlssock_t */
#endif

#if (NXT_HAVE_NJS)
nxt_queue_t js_modules;
nxt_queue_t js_modules;
#endif

nxt_queue_t apps; /* of nxt_app_t */
nxt_queue_t previous; /* of nxt_app_t */
nxt_queue_t apps; /* of nxt_app_t */
nxt_queue_t previous; /* of nxt_app_t */

uint32_t new_threads;
uint32_t stream;
uint32_t count;
uint32_t new_threads;
uint32_t stream;
uint32_t count;

nxt_event_engine_t *engine;
nxt_port_t *port;
nxt_array_t *engines;
nxt_router_conf_t *router_conf;
nxt_mp_t *mem_pool;
nxt_event_engine_t *engine;
nxt_port_t *port;
nxt_array_t *engines;
nxt_router_conf_t *router_conf;
nxt_router_listener_conf_t *listener_conf;
nxt_mp_t *mem_pool;
} nxt_router_temp_conf_t;


Expand Down

0 comments on commit fbf15bd

Please sign in to comment.