nghttpx: Add --single-worker option
Previously, nghttpx will use only one single thread inside the worker process if --workers=1 (this is default). If --workers=N, N > 1, we use additional threads for accepting connections, or API request processing, etc. With this commit, we use the same processing model for N > 1 even if N == 1. To restore the original single thread execution mode, --single-worker option is added. If threading is disabled --single-worker is always true.
This commit is contained in:
parent
0c8b1a4f74
commit
2af57c3cfc
|
@ -162,6 +162,7 @@ OPTIONS = [
|
||||||
"tls-max-proto-version",
|
"tls-max-proto-version",
|
||||||
"redirect-https-port",
|
"redirect-https-port",
|
||||||
"frontend-max-requests",
|
"frontend-max-requests",
|
||||||
|
"single-thread",
|
||||||
]
|
]
|
||||||
|
|
||||||
LOGVARS = [
|
LOGVARS = [
|
||||||
|
|
21
src/shrpx.cc
21
src/shrpx.cc
|
@ -1387,6 +1387,10 @@ void fill_default_config(Config *config) {
|
||||||
config->conf_path = StringRef::from_lit("/etc/nghttpx/nghttpx.conf");
|
config->conf_path = StringRef::from_lit("/etc/nghttpx/nghttpx.conf");
|
||||||
config->pid = getpid();
|
config->pid = getpid();
|
||||||
|
|
||||||
|
#ifdef NOTHREADS
|
||||||
|
config->single_thread = true;
|
||||||
|
#endif // NOTHREADS
|
||||||
|
|
||||||
if (ev_supported_backends() & ~ev_recommended_backends() & EVBACKEND_KQUEUE) {
|
if (ev_supported_backends() & ~ev_recommended_backends() & EVBACKEND_KQUEUE) {
|
||||||
config->ev_loop_flags = ev_recommended_backends() | EVBACKEND_KQUEUE;
|
config->ev_loop_flags = ev_recommended_backends() | EVBACKEND_KQUEUE;
|
||||||
}
|
}
|
||||||
|
@ -1824,6 +1828,12 @@ Performance:
|
||||||
Set the number of worker threads.
|
Set the number of worker threads.
|
||||||
Default: )"
|
Default: )"
|
||||||
<< config->num_worker << R"(
|
<< config->num_worker << R"(
|
||||||
|
--single-thread
|
||||||
|
Run everything in one thread inside the worker process.
|
||||||
|
This feature is provided for better debugging
|
||||||
|
experience, or for the platforms which lack thread
|
||||||
|
support. If threading is disabled, this option is
|
||||||
|
always enabled.
|
||||||
--read-rate=<SIZE>
|
--read-rate=<SIZE>
|
||||||
Set maximum average read rate on frontend connection.
|
Set maximum average read rate on frontend connection.
|
||||||
Setting 0 to this option means read rate is unlimited.
|
Setting 0 to this option means read rate is unlimited.
|
||||||
|
@ -2707,6 +2717,11 @@ int process_options(Config *config,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config->single_thread) {
|
||||||
|
LOG(WARN) << "single-thread: Set workers to 1";
|
||||||
|
config->num_worker = 1;
|
||||||
|
}
|
||||||
|
|
||||||
auto &http2conf = config->http2;
|
auto &http2conf = config->http2;
|
||||||
{
|
{
|
||||||
auto &dumpconf = http2conf.upstream.debug.dump;
|
auto &dumpconf = http2conf.upstream.debug.dump;
|
||||||
|
@ -3276,6 +3291,7 @@ int main(int argc, char **argv) {
|
||||||
{SHRPX_OPT_REDIRECT_HTTPS_PORT.c_str(), required_argument, &flag, 154},
|
{SHRPX_OPT_REDIRECT_HTTPS_PORT.c_str(), required_argument, &flag, 154},
|
||||||
{SHRPX_OPT_FRONTEND_MAX_REQUESTS.c_str(), required_argument, &flag,
|
{SHRPX_OPT_FRONTEND_MAX_REQUESTS.c_str(), required_argument, &flag,
|
||||||
155},
|
155},
|
||||||
|
{SHRPX_OPT_SINGLE_THREAD.c_str(), no_argument, &flag, 156},
|
||||||
{nullptr, 0, nullptr, 0}};
|
{nullptr, 0, nullptr, 0}};
|
||||||
|
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
|
@ -4007,6 +4023,11 @@ int main(int argc, char **argv) {
|
||||||
cmdcfgs.emplace_back(SHRPX_OPT_FRONTEND_MAX_REQUESTS,
|
cmdcfgs.emplace_back(SHRPX_OPT_FRONTEND_MAX_REQUESTS,
|
||||||
StringRef{optarg});
|
StringRef{optarg});
|
||||||
break;
|
break;
|
||||||
|
case 156:
|
||||||
|
// --single-thread
|
||||||
|
cmdcfgs.emplace_back(SHRPX_OPT_SINGLE_THREAD,
|
||||||
|
StringRef::from_lit("yes"));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1573,6 +1573,9 @@ int option_lookup_token(const char *name, size_t namelen) {
|
||||||
if (util::strieq_l("add-forwarde", name, 12)) {
|
if (util::strieq_l("add-forwarde", name, 12)) {
|
||||||
return SHRPX_OPTID_ADD_FORWARDED;
|
return SHRPX_OPTID_ADD_FORWARDED;
|
||||||
}
|
}
|
||||||
|
if (util::strieq_l("single-threa", name, 12)) {
|
||||||
|
return SHRPX_OPTID_SINGLE_THREAD;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
if (util::strieq_l("dh-param-fil", name, 12)) {
|
if (util::strieq_l("dh-param-fil", name, 12)) {
|
||||||
|
@ -3376,6 +3379,10 @@ int parse_config(Config *config, int optid, const StringRef &opt,
|
||||||
}
|
}
|
||||||
case SHRPX_OPTID_FRONTEND_MAX_REQUESTS:
|
case SHRPX_OPTID_FRONTEND_MAX_REQUESTS:
|
||||||
return parse_uint(&config->http.max_requests, opt, optarg);
|
return parse_uint(&config->http.max_requests, opt, optarg);
|
||||||
|
case SHRPX_OPTID_SINGLE_THREAD:
|
||||||
|
config->single_thread = util::strieq_l("yes", optarg);
|
||||||
|
|
||||||
|
return 0;
|
||||||
case SHRPX_OPTID_CONF:
|
case SHRPX_OPTID_CONF:
|
||||||
LOG(WARN) << "conf: ignored";
|
LOG(WARN) << "conf: ignored";
|
||||||
|
|
||||||
|
|
|
@ -335,6 +335,7 @@ constexpr auto SHRPX_OPT_REDIRECT_HTTPS_PORT =
|
||||||
StringRef::from_lit("redirect-https-port");
|
StringRef::from_lit("redirect-https-port");
|
||||||
constexpr auto SHRPX_OPT_FRONTEND_MAX_REQUESTS =
|
constexpr auto SHRPX_OPT_FRONTEND_MAX_REQUESTS =
|
||||||
StringRef::from_lit("frontend-max-requests");
|
StringRef::from_lit("frontend-max-requests");
|
||||||
|
constexpr auto SHRPX_OPT_SINGLE_THREAD = StringRef::from_lit("single-thread");
|
||||||
|
|
||||||
constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8;
|
constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8;
|
||||||
|
|
||||||
|
@ -863,6 +864,7 @@ struct Config {
|
||||||
verbose{false},
|
verbose{false},
|
||||||
daemon{false},
|
daemon{false},
|
||||||
http2_proxy{false},
|
http2_proxy{false},
|
||||||
|
single_thread{false},
|
||||||
ev_loop_flags{0} {}
|
ev_loop_flags{0} {}
|
||||||
~Config();
|
~Config();
|
||||||
|
|
||||||
|
@ -903,6 +905,7 @@ struct Config {
|
||||||
bool verbose;
|
bool verbose;
|
||||||
bool daemon;
|
bool daemon;
|
||||||
bool http2_proxy;
|
bool http2_proxy;
|
||||||
|
bool single_thread;
|
||||||
// flags passed to ev_default_loop() and ev_loop_new()
|
// flags passed to ev_default_loop() and ev_loop_new()
|
||||||
int ev_loop_flags;
|
int ev_loop_flags;
|
||||||
};
|
};
|
||||||
|
@ -1037,6 +1040,7 @@ enum {
|
||||||
SHRPX_OPTID_RESPONSE_HEADER_FIELD_BUFFER,
|
SHRPX_OPTID_RESPONSE_HEADER_FIELD_BUFFER,
|
||||||
SHRPX_OPTID_RLIMIT_NOFILE,
|
SHRPX_OPTID_RLIMIT_NOFILE,
|
||||||
SHRPX_OPTID_SERVER_NAME,
|
SHRPX_OPTID_SERVER_NAME,
|
||||||
|
SHRPX_OPTID_SINGLE_THREAD,
|
||||||
SHRPX_OPTID_STREAM_READ_TIMEOUT,
|
SHRPX_OPTID_STREAM_READ_TIMEOUT,
|
||||||
SHRPX_OPTID_STREAM_WRITE_TIMEOUT,
|
SHRPX_OPTID_STREAM_WRITE_TIMEOUT,
|
||||||
SHRPX_OPTID_STRIP_INCOMING_FORWARDED,
|
SHRPX_OPTID_STRIP_INCOMING_FORWARDED,
|
||||||
|
|
|
@ -333,7 +333,7 @@ void ConnectionHandler::join_worker() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionHandler::graceful_shutdown_worker() {
|
void ConnectionHandler::graceful_shutdown_worker() {
|
||||||
if (get_config()->num_worker == 1) {
|
if (single_worker_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,7 +369,7 @@ int ConnectionHandler::handle_connection(int fd, sockaddr *addr, int addrlen,
|
||||||
|
|
||||||
auto config = get_config();
|
auto config = get_config();
|
||||||
|
|
||||||
if (config->num_worker == 1) {
|
if (single_worker_) {
|
||||||
auto &upstreamconf = config->conn.upstream;
|
auto &upstreamconf = config->conn.upstream;
|
||||||
if (single_worker_->get_worker_stat()->num_connections >=
|
if (single_worker_->get_worker_stat()->num_connections >=
|
||||||
upstreamconf.worker_connections) {
|
upstreamconf.worker_connections) {
|
||||||
|
|
|
@ -123,9 +123,9 @@ void graceful_shutdown(ConnectionHandler *conn_handler) {
|
||||||
|
|
||||||
conn_handler->graceful_shutdown_worker();
|
conn_handler->graceful_shutdown_worker();
|
||||||
|
|
||||||
if (get_config()->num_worker == 1) {
|
auto single_worker = conn_handler->get_single_worker();
|
||||||
if (conn_handler->get_single_worker()->get_worker_stat()->num_connections ==
|
if (single_worker) {
|
||||||
0) {
|
if (single_worker->get_worker_stat()->num_connections == 0) {
|
||||||
ev_break(conn_handler->get_loop());
|
ev_break(conn_handler->get_loop());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,9 +144,7 @@ void reopen_log(ConnectionHandler *conn_handler) {
|
||||||
(void)reopen_log_files(loggingconf);
|
(void)reopen_log_files(loggingconf);
|
||||||
redirect_stderr_to_errorlog(loggingconf);
|
redirect_stderr_to_errorlog(loggingconf);
|
||||||
|
|
||||||
if (get_config()->num_worker > 1) {
|
conn_handler->worker_reopen_log_files();
|
||||||
conn_handler->worker_reopen_log_files();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@ -508,7 +506,7 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->num_worker == 1) {
|
if (config->single_thread) {
|
||||||
rv = conn_handler.create_single_worker();
|
rv = conn_handler.create_single_worker();
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
Loading…
Reference in New Issue