nghttpx: Bring per-connection rate limit back

--read-burst=0 still does not work.  But specifying n > 0 workarounds
this.
This commit is contained in:
Tatsuhiro Tsujikawa 2014-08-17 16:17:10 +09:00
parent 02c347fe6b
commit 5d2390deba
4 changed files with 104 additions and 0 deletions

View File

@ -770,6 +770,11 @@ void fill_default_config()
mod_config()->downstream_http_proxy_host = nullptr; mod_config()->downstream_http_proxy_host = nullptr;
mod_config()->downstream_http_proxy_port = 0; mod_config()->downstream_http_proxy_port = 0;
mod_config()->downstream_http_proxy_addrlen = 0; mod_config()->downstream_http_proxy_addrlen = 0;
mod_config()->rate_limit_cfg = nullptr;
mod_config()->read_rate = 0;
mod_config()->read_burst = 1 << 30;
mod_config()->write_rate = 0;
mod_config()->write_burst = 0;
mod_config()->worker_read_rate = 0; mod_config()->worker_read_rate = 0;
mod_config()->worker_read_burst = 0; mod_config()->worker_read_burst = 0;
mod_config()->worker_write_rate = 0; mod_config()->worker_write_rate = 0;
@ -864,6 +869,29 @@ Performance:
Set the number of worker threads. Set the number of worker threads.
Default: )" Default: )"
<< get_config()->num_worker << R"( << get_config()->num_worker << R"(
--read-rate=<RATE>
Set maximum average read rate on frontend
connection. Setting 0 to this option means read
rate is unlimited.
Default: )"
<< get_config()->read_rate << R"(
--read-burst=<SIZE>
Set maximum read burst size on frontend
connection. Setting 0 does not work.
Default: )"
<< get_config()->read_burst << R"(
--write-rate=<RATE>
Set maximum average write rate on frontend
connection. Setting 0 to this option means write
rate is unlimited.
Default: )"
<< get_config()->write_rate << R"(
--write-burst=<SIZE>
Set maximum write burst size on frontend
connection. Setting 0 to this option means write
burst size is unlimited.
Default: )"
<< get_config()->write_burst << R"(
--worker-read-rate=<RATE> --worker-read-rate=<RATE>
Set maximum average read rate on frontend Set maximum average read rate on frontend
connection per worker. Setting 0 to this option connection per worker. Setting 0 to this option
@ -1229,6 +1257,10 @@ int main(int argc, char **argv)
{"frontend-no-tls", no_argument, &flag, 29}, {"frontend-no-tls", no_argument, &flag, 29},
{"backend-tls-sni-field", required_argument, &flag, 31}, {"backend-tls-sni-field", required_argument, &flag, 31},
{"dh-param-file", required_argument, &flag, 33}, {"dh-param-file", required_argument, &flag, 33},
{"read-rate", required_argument, &flag, 34},
{"read-burst", required_argument, &flag, 35},
{"write-rate", required_argument, &flag, 36},
{"write-burst", required_argument, &flag, 37},
{"npn-list", required_argument, &flag, 38}, {"npn-list", required_argument, &flag, 38},
{"verify-client", no_argument, &flag, 39}, {"verify-client", no_argument, &flag, 39},
{"verify-client-cacert", required_argument, &flag, 40}, {"verify-client-cacert", required_argument, &flag, 40},
@ -1423,6 +1455,22 @@ int main(int argc, char **argv)
// --dh-param-file // --dh-param-file
cmdcfgs.emplace_back(SHRPX_OPT_DH_PARAM_FILE, optarg); cmdcfgs.emplace_back(SHRPX_OPT_DH_PARAM_FILE, optarg);
break; break;
case 34:
// --read-rate
cmdcfgs.emplace_back(SHRPX_OPT_READ_RATE, optarg);
break;
case 35:
// --read-burst
cmdcfgs.emplace_back(SHRPX_OPT_READ_BURST, optarg);
break;
case 36:
// --write-rate
cmdcfgs.emplace_back(SHRPX_OPT_WRITE_RATE, optarg);
break;
case 37:
// --write-burst
cmdcfgs.emplace_back(SHRPX_OPT_WRITE_BURST, optarg);
break;
case 38: case 38:
// --npn-list // --npn-list
cmdcfgs.emplace_back(SHRPX_OPT_NPN_LIST, optarg); cmdcfgs.emplace_back(SHRPX_OPT_NPN_LIST, optarg);
@ -1771,6 +1819,13 @@ int main(int argc, char **argv)
} }
} }
mod_config()->rate_limit_cfg = ev_token_bucket_cfg_new
(get_rate_limit(get_config()->read_rate),
get_rate_limit(get_config()->read_burst),
get_rate_limit(get_config()->write_rate),
get_rate_limit(get_config()->write_burst),
nullptr);
mod_config()->worker_rate_limit_cfg = ev_token_bucket_cfg_new mod_config()->worker_rate_limit_cfg = ev_token_bucket_cfg_new
(get_rate_limit(get_config()->worker_read_rate), (get_rate_limit(get_config()->worker_read_rate),
get_rate_limit(get_config()->worker_read_burst), get_rate_limit(get_config()->worker_read_burst),

View File

@ -238,6 +238,11 @@ ClientHandler::ClientHandler(bufferevent *bev,
++worker_stat->num_connections; ++worker_stat->num_connections;
rv = bufferevent_set_rate_limit(bev_, get_config()->rate_limit_cfg);
if(rv == -1) {
CLOG(FATAL, this) << "bufferevent_set_rate_limit() failed";
}
rv = bufferevent_add_to_rate_limit_group(bev_, rate_limit_group); rv = bufferevent_add_to_rate_limit_group(bev_, rate_limit_group);
if(rv == -1) { if(rv == -1) {
CLOG(FATAL, this) << "bufferevent_add_to_rate_limit_group() failed"; CLOG(FATAL, this) << "bufferevent_add_to_rate_limit_group() failed";

View File

@ -103,6 +103,10 @@ const char SHRPX_OPT_CACERT[] = "cacert";
const char SHRPX_OPT_BACKEND_IPV4[] = "backend-ipv4"; const char SHRPX_OPT_BACKEND_IPV4[] = "backend-ipv4";
const char SHRPX_OPT_BACKEND_IPV6[] = "backend-ipv6"; const char SHRPX_OPT_BACKEND_IPV6[] = "backend-ipv6";
const char SHRPX_OPT_BACKEND_HTTP_PROXY_URI[] = "backend-http-proxy-uri"; const char SHRPX_OPT_BACKEND_HTTP_PROXY_URI[] = "backend-http-proxy-uri";
const char SHRPX_OPT_READ_RATE[] = "read-rate";
const char SHRPX_OPT_READ_BURST[] = "read-burst";
const char SHRPX_OPT_WRITE_RATE[] = "write-rate";
const char SHRPX_OPT_WRITE_BURST[] = "write-burst";
const char SHRPX_OPT_WORKER_READ_RATE[] = "worker-read-rate"; const char SHRPX_OPT_WORKER_READ_RATE[] = "worker-read-rate";
const char SHRPX_OPT_WORKER_READ_BURST[] = "worker-read-burst"; const char SHRPX_OPT_WORKER_READ_BURST[] = "worker-read-burst";
const char SHRPX_OPT_WORKER_WRITE_RATE[] = "worker-write-rate"; const char SHRPX_OPT_WORKER_WRITE_RATE[] = "worker-write-rate";
@ -670,6 +674,40 @@ int parse_config(const char *opt, const char *optarg)
return 0; return 0;
} }
if(util::strieq(opt, SHRPX_OPT_READ_RATE)) {
mod_config()->read_rate = strtoul(optarg, nullptr, 10);
return 0;
}
if(util::strieq(opt, SHRPX_OPT_READ_BURST)) {
errno = 0;
auto n = strtoul(optarg, nullptr, 10);
if(errno != 0 || n == 0) {
LOG(ERROR) << SHRPX_OPT_READ_BURST
<< ": specify integer strictly larger than 0";
return -1;
}
mod_config()->read_burst = n;
return 0;
}
if(util::strieq(opt, SHRPX_OPT_WRITE_RATE)) {
mod_config()->write_rate = strtoul(optarg, nullptr, 10);
return 0;
}
if(util::strieq(opt, SHRPX_OPT_WRITE_BURST)) {
mod_config()->write_burst = strtoul(optarg, nullptr, 10);
return 0;
}
if(util::strieq(opt, SHRPX_OPT_WORKER_READ_RATE)) { if(util::strieq(opt, SHRPX_OPT_WORKER_READ_RATE)) {
mod_config()->worker_read_rate = strtoul(optarg, nullptr, 10); mod_config()->worker_read_rate = strtoul(optarg, nullptr, 10);

View File

@ -96,6 +96,10 @@ extern const char SHRPX_OPT_BACKEND_IPV4[];
extern const char SHRPX_OPT_BACKEND_IPV6[]; extern const char SHRPX_OPT_BACKEND_IPV6[];
extern const char SHRPX_OPT_BACKEND_HTTP_PROXY_URI[]; extern const char SHRPX_OPT_BACKEND_HTTP_PROXY_URI[];
extern const char SHRPX_OPT_BACKEND_TLS_SNI_FIELD[]; extern const char SHRPX_OPT_BACKEND_TLS_SNI_FIELD[];
extern const char SHRPX_OPT_READ_RATE[];
extern const char SHRPX_OPT_READ_BURST[];
extern const char SHRPX_OPT_WRITE_RATE[];
extern const char SHRPX_OPT_WRITE_BURST[];
extern const char SHRPX_OPT_WORKER_READ_RATE[]; extern const char SHRPX_OPT_WORKER_READ_RATE[];
extern const char SHRPX_OPT_WORKER_READ_BURST[]; extern const char SHRPX_OPT_WORKER_READ_BURST[];
extern const char SHRPX_OPT_WORKER_WRITE_RATE[]; extern const char SHRPX_OPT_WORKER_WRITE_RATE[];
@ -190,6 +194,8 @@ struct Config {
std::unique_ptr<char[]> downstream_http_proxy_host; std::unique_ptr<char[]> downstream_http_proxy_host;
std::unique_ptr<char[]> http2_upstream_dump_request_header_file; std::unique_ptr<char[]> http2_upstream_dump_request_header_file;
std::unique_ptr<char[]> http2_upstream_dump_response_header_file; std::unique_ptr<char[]> http2_upstream_dump_response_header_file;
// Rate limit configuration per connection
ev_token_bucket_cfg *rate_limit_cfg;
// Rate limit configuration per worker (thread) // Rate limit configuration per worker (thread)
ev_token_bucket_cfg *worker_rate_limit_cfg; ev_token_bucket_cfg *worker_rate_limit_cfg;
// list of supported NPN/ALPN protocol strings in the order of // list of supported NPN/ALPN protocol strings in the order of