nghttpx: Add --backend-fall and --backend-rise options

These options are analogous to fall and rise parameter found in
haproxy.
This commit is contained in:
Tatsuhiro Tsujikawa 2016-04-08 22:35:45 +09:00
parent f9b872ab78
commit 7bc35044c7
6 changed files with 62 additions and 3 deletions

View File

@ -129,6 +129,8 @@ OPTIONS = [
"backend-tls", "backend-tls",
"backend-connections-per-host", "backend-connections-per-host",
"error-page", "error-page",
"backend-fall",
"backend-rise",
] ]
LOGVARS = [ LOGVARS = [

View File

@ -1314,6 +1314,24 @@ Connections:
--backend-write-timeout options. --backend-write-timeout options.
--accept-proxy-protocol --accept-proxy-protocol
Accept PROXY protocol version 1 on frontend connection. Accept PROXY protocol version 1 on frontend connection.
--backend-fall=<N>
If nghttpx cannot connect to a specific backend <N>
times in a row, that backend is assumed to be offline,
and it is excluded from load balancing. See also
--backend-rise option. If <N> is 0, a backend never be
excluded from load balancing whatever times nghttpx
cannot connect to it.
Default: )" << get_config()->conn.downstream.fall << R"(
--backend-rise=<N>
As described in --backend-fall, a backend is excluded
from load balancing if nghttpx assumes that it is
offline. Then nghttpx periodically attempts to make a
connection to the failed backend, and if the connection
is made successfully <N> times in a row, the backend is
assumed to be online, and it is now eligible for load
balancing target. If <N> is 0, a backend is permanently
offline, once it goes in that state.
Default: )" << get_config()->conn.downstream.rise << R"(
Performance: Performance:
-n, --workers=<N> -n, --workers=<N>
@ -2519,6 +2537,8 @@ int main(int argc, char **argv) {
{SHRPX_OPT_BACKEND_CONNECTIONS_PER_HOST.c_str(), required_argument, {SHRPX_OPT_BACKEND_CONNECTIONS_PER_HOST.c_str(), required_argument,
&flag, 121}, &flag, 121},
{SHRPX_OPT_ERROR_PAGE.c_str(), required_argument, &flag, 122}, {SHRPX_OPT_ERROR_PAGE.c_str(), required_argument, &flag, 122},
{SHRPX_OPT_BACKEND_FALL.c_str(), required_argument, &flag, 123},
{SHRPX_OPT_BACKEND_RISE.c_str(), required_argument, &flag, 124},
{nullptr, 0, nullptr, 0}}; {nullptr, 0, nullptr, 0}};
int option_index = 0; int option_index = 0;
@ -3094,6 +3114,14 @@ int main(int argc, char **argv) {
// --error-page // --error-page
cmdcfgs.emplace_back(SHRPX_OPT_ERROR_PAGE, StringRef{optarg}); cmdcfgs.emplace_back(SHRPX_OPT_ERROR_PAGE, StringRef{optarg});
break; break;
case 123:
// --backend-fall
cmdcfgs.emplace_back(SHRPX_OPT_BACKEND_FALL, StringRef{optarg});
break;
case 124:
// --backend-rise
cmdcfgs.emplace_back(SHRPX_OPT_BACKEND_RISE, StringRef{optarg});
break;
default: default:
break; break;
} }

View File

@ -893,6 +893,7 @@ enum {
SHRPX_OPTID_BACKEND_ADDRESS_FAMILY, SHRPX_OPTID_BACKEND_ADDRESS_FAMILY,
SHRPX_OPTID_BACKEND_CONNECTIONS_PER_FRONTEND, SHRPX_OPTID_BACKEND_CONNECTIONS_PER_FRONTEND,
SHRPX_OPTID_BACKEND_CONNECTIONS_PER_HOST, SHRPX_OPTID_BACKEND_CONNECTIONS_PER_HOST,
SHRPX_OPTID_BACKEND_FALL,
SHRPX_OPTID_BACKEND_HTTP_PROXY_URI, SHRPX_OPTID_BACKEND_HTTP_PROXY_URI,
SHRPX_OPTID_BACKEND_HTTP1_CONNECTIONS_PER_FRONTEND, SHRPX_OPTID_BACKEND_HTTP1_CONNECTIONS_PER_FRONTEND,
SHRPX_OPTID_BACKEND_HTTP1_CONNECTIONS_PER_HOST, SHRPX_OPTID_BACKEND_HTTP1_CONNECTIONS_PER_HOST,
@ -908,6 +909,7 @@ enum {
SHRPX_OPTID_BACKEND_READ_TIMEOUT, SHRPX_OPTID_BACKEND_READ_TIMEOUT,
SHRPX_OPTID_BACKEND_REQUEST_BUFFER, SHRPX_OPTID_BACKEND_REQUEST_BUFFER,
SHRPX_OPTID_BACKEND_RESPONSE_BUFFER, SHRPX_OPTID_BACKEND_RESPONSE_BUFFER,
SHRPX_OPTID_BACKEND_RISE,
SHRPX_OPTID_BACKEND_TLS, SHRPX_OPTID_BACKEND_TLS,
SHRPX_OPTID_BACKEND_TLS_SNI_FIELD, SHRPX_OPTID_BACKEND_TLS_SNI_FIELD,
SHRPX_OPTID_BACKEND_WRITE_TIMEOUT, SHRPX_OPTID_BACKEND_WRITE_TIMEOUT,
@ -1187,6 +1189,9 @@ int option_lookup_token(const char *name, size_t namelen) {
} }
break; break;
case 'e': case 'e':
if (util::strieq_l("backend-ris", name, 11)) {
return SHRPX_OPTID_BACKEND_RISE;
}
if (util::strieq_l("host-rewrit", name, 11)) { if (util::strieq_l("host-rewrit", name, 11)) {
return SHRPX_OPTID_HOST_REWRITE; return SHRPX_OPTID_HOST_REWRITE;
} }
@ -1194,6 +1199,11 @@ int option_lookup_token(const char *name, size_t namelen) {
return SHRPX_OPTID_HTTP2_BRIDGE; return SHRPX_OPTID_HTTP2_BRIDGE;
} }
break; break;
case 'l':
if (util::strieq_l("backend-fal", name, 11)) {
return SHRPX_OPTID_BACKEND_FALL;
}
break;
case 'y': case 'y':
if (util::strieq_l("client-prox", name, 11)) { if (util::strieq_l("client-prox", name, 11)) {
return SHRPX_OPTID_CLIENT_PROXY; return SHRPX_OPTID_CLIENT_PROXY;
@ -2672,6 +2682,10 @@ int parse_config(const StringRef &opt, const StringRef &optarg,
opt, optarg); opt, optarg);
case SHRPX_OPTID_ERROR_PAGE: case SHRPX_OPTID_ERROR_PAGE:
return parse_error_page(mod_config()->http.error_pages, opt, optarg); return parse_error_page(mod_config()->http.error_pages, opt, optarg);
case SHRPX_OPTID_BACKEND_FALL:
return parse_uint(&mod_config()->conn.downstream.fall, opt, optarg);
case SHRPX_OPTID_BACKEND_RISE:
return parse_uint(&mod_config()->conn.downstream.rise, opt, optarg);
case SHRPX_OPTID_CONF: case SHRPX_OPTID_CONF:
LOG(WARN) << "conf: ignored"; LOG(WARN) << "conf: ignored";

View File

@ -275,6 +275,8 @@ constexpr auto SHRPX_OPT_BACKEND_TLS = StringRef::from_lit("backend-tls");
constexpr auto SHRPX_OPT_BACKEND_CONNECTIONS_PER_HOST = constexpr auto SHRPX_OPT_BACKEND_CONNECTIONS_PER_HOST =
StringRef::from_lit("backend-connections-per-host"); StringRef::from_lit("backend-connections-per-host");
constexpr auto SHRPX_OPT_ERROR_PAGE = StringRef::from_lit("error-page"); constexpr auto SHRPX_OPT_ERROR_PAGE = StringRef::from_lit("error-page");
constexpr auto SHRPX_OPT_BACKEND_FALL = StringRef::from_lit("backend-fall");
constexpr auto SHRPX_OPT_BACKEND_RISE = StringRef::from_lit("backend-rise");
constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8; constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8;
@ -615,6 +617,8 @@ struct ConnectionConfig {
size_t connections_per_frontend; size_t connections_per_frontend;
size_t request_buffer_size; size_t request_buffer_size;
size_t response_buffer_size; size_t response_buffer_size;
size_t fall;
size_t rise;
// Address family of backend connection. One of either AF_INET, // Address family of backend connection. One of either AF_INET,
// AF_INET6 or AF_UNSPEC. This is ignored if backend connection // AF_INET6 or AF_UNSPEC. This is ignored if backend connection
// is made via Unix domain socket. // is made via Unix domain socket.

View File

@ -294,7 +294,9 @@ void LiveCheck::on_success() {
LOG(WARN) << "Liveness check for " << util::to_numeric_addr(&addr_->addr) LOG(WARN) << "Liveness check for " << util::to_numeric_addr(&addr_->addr)
<< " succeeded " << success_count_ << " time(s) in a row"; << " succeeded " << success_count_ << " time(s) in a row";
if (success_count_ < 3) { auto &downstreamconf = get_config()->conn.downstream;
if (success_count_ < downstreamconf.rise) {
disconnect(); disconnect();
schedule(); schedule();

View File

@ -475,12 +475,21 @@ void downstream_failure(DownstreamAddr *addr) {
auto fail_count = connect_blocker->get_fail_count(); auto fail_count = connect_blocker->get_fail_count();
if (fail_count >= 3) { auto &downstreamconf = get_config()->conn.downstream;
if (downstreamconf.fall == 0) {
return;
}
if (fail_count >= downstreamconf.fall) {
LOG(WARN) << "Could not connect to " << util::to_numeric_addr(&addr->addr) LOG(WARN) << "Could not connect to " << util::to_numeric_addr(&addr->addr)
<< " " << fail_count << " times in a row; considered as offline"; << " " << fail_count << " times in a row; considered as offline";
connect_blocker->offline(); connect_blocker->offline();
addr->live_check->schedule();
if (downstreamconf.rise) {
addr->live_check->schedule();
}
} }
} }