首先,我看到了许多与
backlog
相关的问题,但已知解决了一个谜团:是否可以在不关闭套接字(并重新调用backlog
和 listen()
)?我想要做的是在运行时动态更改我的服务器应用程序的 bind()
。目前,由于thundering herd问题,服务器出现启动问题(所有客户端都在启动时尝试连接)。有500个客户。为了解决这个问题,我将 listen()
减少到 10。这极大地帮助服务器从启动负载中恢复。但是,一旦服务器恢复,我想通过修改
backlog
值来扩大底层队列。那么,有没有一种方法可以在不关闭套接字的情况下更改backlog
?
我在互联网上看到的事情是行不通的,那就是通过传递不同的
backlog
值来通过同一个监听套接字进行第二次 backlog
调用。这是一个聪明的想法,但是 MSDN 明确指出它不会对
listen()
参数产生影响。在 Linux 上,您可以再次调用
backlog
backlog
listen()
来更改积压。
我写了一个测试程序,调用
ngx_cycle_t *
ngx_init_cycle(ngx_cycle_t *old_cycle)
{
if (ngx_open_listening_sockets(cycle) != NGX_OK) {
goto failed;
}
if (!ngx_test_config) {
ngx_configure_listening_sockets(cycle);
}
}
ngx_int_t
ngx_open_listening_sockets(ngx_cycle_t *cycle)
{
if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) {
// ...
}
if (listen(s, ls[i].backlog) == -1) {
// ...
}
}
void
ngx_configure_listening_sockets(ngx_cycle_t *cycle)
{
// set socket options
// ...
if (ls[i].listen) {
/* change backlog via listen() */
if (listen(ls[i].fd, ls[i].backlog) == -1) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
"listen() to %V, backlog %d failed, ignored",
&ls[i].addr_text, ls[i].backlog);
}
}
}
两次,成功了。