nghttpx: Add --frontend-max-requests option
This commit is contained in:
parent
e2b9590c0f
commit
9d16292fe4
|
@ -161,6 +161,7 @@ OPTIONS = [
|
|||
"tls-min-proto-version",
|
||||
"tls-max-proto-version",
|
||||
"redirect-https-port",
|
||||
"frontend-max-requests",
|
||||
]
|
||||
|
||||
LOGVARS = [
|
||||
|
|
15
src/shrpx.cc
15
src/shrpx.cc
|
@ -1448,6 +1448,7 @@ void fill_default_config(Config *config) {
|
|||
httpconf.response_header_field_buffer = 64_k;
|
||||
httpconf.max_response_header_fields = 500;
|
||||
httpconf.redirect_https_port = StringRef::from_lit("443");
|
||||
httpconf.max_requests = std::numeric_limits<size_t>::max();
|
||||
|
||||
auto &http2conf = config->http2;
|
||||
{
|
||||
|
@ -2581,6 +2582,13 @@ DNS:
|
|||
lookup.
|
||||
Default: )"
|
||||
<< config->dns.max_try << R"(
|
||||
--frontend-max-requests=<N>
|
||||
The number of requests that single frontend connection
|
||||
can process. For HTTP/2, this is the number of streams
|
||||
in one HTTP/2 connection. For HTTP/1, this is the
|
||||
number of keep alive requests. This is hint to nghttpx,
|
||||
and it may allow additional few requests. The default
|
||||
value is unlimited.
|
||||
|
||||
Debug:
|
||||
--frontend-http2-dump-request-header=<PATH>
|
||||
|
@ -3266,6 +3274,8 @@ int main(int argc, char **argv) {
|
|||
{SHRPX_OPT_TLS_MAX_PROTO_VERSION.c_str(), required_argument, &flag,
|
||||
153},
|
||||
{SHRPX_OPT_REDIRECT_HTTPS_PORT.c_str(), required_argument, &flag, 154},
|
||||
{SHRPX_OPT_FRONTEND_MAX_REQUESTS.c_str(), required_argument, &flag,
|
||||
155},
|
||||
{nullptr, 0, nullptr, 0}};
|
||||
|
||||
int option_index = 0;
|
||||
|
@ -3992,6 +4002,11 @@ int main(int argc, char **argv) {
|
|||
// --redirect-https-port
|
||||
cmdcfgs.emplace_back(SHRPX_OPT_REDIRECT_HTTPS_PORT, StringRef{optarg});
|
||||
break;
|
||||
case 155:
|
||||
// --frontend-max-requests
|
||||
cmdcfgs.emplace_back(SHRPX_OPT_FRONTEND_MAX_REQUESTS,
|
||||
StringRef{optarg});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1817,6 +1817,11 @@ int option_lookup_token(const char *name, size_t namelen) {
|
|||
return SHRPX_OPTID_TLS_TICKET_KEY_CIPHER;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
if (util::strieq_l("frontend-max-request", name, 20)) {
|
||||
return SHRPX_OPTID_FRONTEND_MAX_REQUESTS;
|
||||
}
|
||||
break;
|
||||
case 't':
|
||||
if (util::strieq_l("backend-write-timeou", name, 20)) {
|
||||
return SHRPX_OPTID_BACKEND_WRITE_TIMEOUT;
|
||||
|
@ -3369,6 +3374,8 @@ int parse_config(Config *config, int optid, const StringRef &opt,
|
|||
config->http.redirect_https_port = optarg;
|
||||
return 0;
|
||||
}
|
||||
case SHRPX_OPTID_FRONTEND_MAX_REQUESTS:
|
||||
return parse_uint(&config->http.max_requests, opt, optarg);
|
||||
case SHRPX_OPTID_CONF:
|
||||
LOG(WARN) << "conf: ignored";
|
||||
|
||||
|
|
|
@ -333,6 +333,8 @@ constexpr auto SHRPX_OPT_TLS_MAX_PROTO_VERSION =
|
|||
StringRef::from_lit("tls-max-proto-version");
|
||||
constexpr auto SHRPX_OPT_REDIRECT_HTTPS_PORT =
|
||||
StringRef::from_lit("redirect-https-port");
|
||||
constexpr auto SHRPX_OPT_FRONTEND_MAX_REQUESTS =
|
||||
StringRef::from_lit("frontend-max-requests");
|
||||
|
||||
constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8;
|
||||
|
||||
|
@ -647,6 +649,7 @@ struct HttpConfig {
|
|||
size_t max_request_header_fields;
|
||||
size_t response_header_field_buffer;
|
||||
size_t max_response_header_fields;
|
||||
size_t max_requests;
|
||||
bool no_via;
|
||||
bool no_location_rewrite;
|
||||
bool no_host_rewrite;
|
||||
|
@ -994,6 +997,7 @@ enum {
|
|||
SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_BITS,
|
||||
SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_SIZE,
|
||||
SHRPX_OPTID_FRONTEND_KEEP_ALIVE_TIMEOUT,
|
||||
SHRPX_OPTID_FRONTEND_MAX_REQUESTS,
|
||||
SHRPX_OPTID_FRONTEND_NO_TLS,
|
||||
SHRPX_OPTID_FRONTEND_READ_TIMEOUT,
|
||||
SHRPX_OPTID_FRONTEND_WRITE_TIMEOUT,
|
||||
|
|
|
@ -271,16 +271,21 @@ int on_begin_headers_callback(nghttp2_session *session,
|
|||
<< frame->hd.stream_id;
|
||||
}
|
||||
|
||||
auto handler = upstream->get_client_handler();
|
||||
upstream->on_start_request(frame);
|
||||
|
||||
auto downstream = make_unique<Downstream>(upstream, handler->get_mcpool(),
|
||||
return 0;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void Http2Upstream::on_start_request(const nghttp2_frame *frame) {
|
||||
auto downstream = make_unique<Downstream>(this, handler_->get_mcpool(),
|
||||
frame->hd.stream_id);
|
||||
nghttp2_session_set_stream_user_data(session, frame->hd.stream_id,
|
||||
nghttp2_session_set_stream_user_data(session_, frame->hd.stream_id,
|
||||
downstream.get());
|
||||
|
||||
downstream->reset_upstream_rtimer();
|
||||
|
||||
handler->repeat_read_timer();
|
||||
handler_->repeat_read_timer();
|
||||
|
||||
auto &req = downstream->request();
|
||||
|
||||
|
@ -289,11 +294,16 @@ int on_begin_headers_callback(nghttp2_session *session,
|
|||
req.http_major = 2;
|
||||
req.http_minor = 0;
|
||||
|
||||
upstream->add_pending_downstream(std::move(downstream));
|
||||
add_pending_downstream(std::move(downstream));
|
||||
|
||||
return 0;
|
||||
++num_requests_;
|
||||
|
||||
auto config = get_config();
|
||||
auto &httpconf = config->http;
|
||||
if (httpconf.max_requests <= num_requests_) {
|
||||
start_graceful_shutdown();
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
int Http2Upstream::on_request_headers(Downstream *downstream,
|
||||
const nghttp2_frame *frame) {
|
||||
|
@ -873,8 +883,6 @@ void Http2Upstream::submit_goaway() {
|
|||
}
|
||||
|
||||
void Http2Upstream::check_shutdown() {
|
||||
int rv;
|
||||
|
||||
auto worker = handler_->get_worker();
|
||||
|
||||
if (!worker->get_graceful_shutdown()) {
|
||||
|
@ -883,6 +891,15 @@ void Http2Upstream::check_shutdown() {
|
|||
|
||||
ev_prepare_stop(handler_->get_loop(), &prep_);
|
||||
|
||||
start_graceful_shutdown();
|
||||
}
|
||||
|
||||
void Http2Upstream::start_graceful_shutdown() {
|
||||
int rv;
|
||||
if (ev_is_active(&shutdown_timer_)) {
|
||||
return;
|
||||
}
|
||||
|
||||
rv = nghttp2_submit_shutdown_notice(session_);
|
||||
if (rv != 0) {
|
||||
ULOG(FATAL, this) << "nghttp2_submit_shutdown_notice() failed: "
|
||||
|
@ -965,7 +982,8 @@ Http2Upstream::Http2Upstream(ClientHandler *handler)
|
|||
!get_config()->http2_proxy),
|
||||
handler_(handler),
|
||||
session_(nullptr),
|
||||
max_buffer_size_(MAX_BUFFER_SIZE) {
|
||||
max_buffer_size_(MAX_BUFFER_SIZE),
|
||||
num_requests_(0) {
|
||||
int rv;
|
||||
|
||||
auto config = get_config();
|
||||
|
|
|
@ -111,11 +111,15 @@ public:
|
|||
|
||||
void submit_goaway();
|
||||
void check_shutdown();
|
||||
// Starts graceful shutdown period.
|
||||
void start_graceful_shutdown();
|
||||
|
||||
int prepare_push_promise(Downstream *downstream);
|
||||
int submit_push_promise(const StringRef &scheme, const StringRef &authority,
|
||||
const StringRef &path, Downstream *downstream);
|
||||
|
||||
// Called when new request has started.
|
||||
void on_start_request(const nghttp2_frame *frame);
|
||||
int on_request_headers(Downstream *downstream, const nghttp2_frame *frame);
|
||||
|
||||
DefaultMemchunks *get_response_buf();
|
||||
|
@ -134,6 +138,8 @@ private:
|
|||
ClientHandler *handler_;
|
||||
nghttp2_session *session_;
|
||||
size_t max_buffer_size_;
|
||||
// The number of requests seen so far.
|
||||
size_t num_requests_;
|
||||
bool flow_control_;
|
||||
};
|
||||
|
||||
|
|
|
@ -52,7 +52,8 @@ namespace shrpx {
|
|||
HttpsUpstream::HttpsUpstream(ClientHandler *handler)
|
||||
: handler_(handler),
|
||||
current_header_length_(0),
|
||||
ioctrl_(handler->get_rlimit()) {
|
||||
ioctrl_(handler->get_rlimit()),
|
||||
num_requests_(0) {
|
||||
http_parser_init(&htp_, HTTP_REQUEST);
|
||||
htp_.data = this;
|
||||
}
|
||||
|
@ -63,27 +64,30 @@ void HttpsUpstream::reset_current_header_length() {
|
|||
current_header_length_ = 0;
|
||||
}
|
||||
|
||||
namespace {
|
||||
int htp_msg_begin(http_parser *htp) {
|
||||
auto upstream = static_cast<HttpsUpstream *>(htp->data);
|
||||
void HttpsUpstream::on_start_request() {
|
||||
if (LOG_ENABLED(INFO)) {
|
||||
ULOG(INFO, upstream) << "HTTP request started";
|
||||
ULOG(INFO, this) << "HTTP request started";
|
||||
}
|
||||
upstream->reset_current_header_length();
|
||||
reset_current_header_length();
|
||||
|
||||
auto handler = upstream->get_client_handler();
|
||||
auto downstream = make_unique<Downstream>(this, handler_->get_mcpool(), 0);
|
||||
|
||||
auto downstream = make_unique<Downstream>(upstream, handler->get_mcpool(), 0);
|
||||
attach_downstream(std::move(downstream));
|
||||
|
||||
upstream->attach_downstream(std::move(downstream));
|
||||
|
||||
auto conn = handler->get_connection();
|
||||
auto conn = handler_->get_connection();
|
||||
auto &upstreamconf = get_config()->conn.upstream;
|
||||
|
||||
conn->rt.repeat = upstreamconf.timeout.read;
|
||||
|
||||
handler->repeat_read_timer();
|
||||
handler_->repeat_read_timer();
|
||||
|
||||
++num_requests_;
|
||||
}
|
||||
|
||||
namespace {
|
||||
int htp_msg_begin(http_parser *htp) {
|
||||
auto upstream = static_cast<HttpsUpstream *>(htp->data);
|
||||
upstream->on_start_request();
|
||||
return 0;
|
||||
}
|
||||
} // namespace
|
||||
|
@ -868,12 +872,14 @@ int HttpsUpstream::send_reply(Downstream *downstream, const uint8_t *body,
|
|||
auto &resp = downstream->response();
|
||||
auto &balloc = downstream->get_block_allocator();
|
||||
auto config = get_config();
|
||||
auto &httpconf = config->http;
|
||||
|
||||
auto connection_close = false;
|
||||
|
||||
auto worker = handler_->get_worker();
|
||||
|
||||
if (worker->get_graceful_shutdown()) {
|
||||
if (httpconf.max_requests <= num_requests_ &&
|
||||
worker->get_graceful_shutdown()) {
|
||||
resp.fs.add_header_token(StringRef::from_lit("connection"),
|
||||
StringRef::from_lit("close"), false,
|
||||
http2::HD_CONNECTION);
|
||||
|
@ -917,8 +923,6 @@ int HttpsUpstream::send_reply(Downstream *downstream, const uint8_t *body,
|
|||
output->append("\r\n");
|
||||
}
|
||||
|
||||
auto &httpconf = config->http;
|
||||
|
||||
for (auto &p : httpconf.add_response_headers) {
|
||||
output->append(p.name);
|
||||
output->append(": ");
|
||||
|
@ -1078,7 +1082,8 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
|
|||
|
||||
// after graceful shutdown commenced, add connection: close header
|
||||
// field.
|
||||
if (worker->get_graceful_shutdown()) {
|
||||
if (httpconf.max_requests <= num_requests_ ||
|
||||
worker->get_graceful_shutdown()) {
|
||||
resp.connection_close = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -95,12 +95,17 @@ public:
|
|||
void log_response_headers(DefaultMemchunks *buf) const;
|
||||
int redirect_to_https(Downstream *downstream);
|
||||
|
||||
// Called when new request has started.
|
||||
void on_start_request();
|
||||
|
||||
private:
|
||||
ClientHandler *handler_;
|
||||
http_parser htp_;
|
||||
size_t current_header_length_;
|
||||
std::unique_ptr<Downstream> downstream_;
|
||||
IOControl ioctrl_;
|
||||
// The number of requests seen so far.
|
||||
size_t num_requests_;
|
||||
};
|
||||
|
||||
} // namespace shrpx
|
||||
|
|
Loading…
Reference in New Issue