nghttpx: Pool h1 backend connection per address
Pool HTTP/1.1 backend connection per address and reuse it only when the next round robin index refers to this address. Previously if there is a pooled connection, there is no round robin selection.
This commit is contained in:
parent
803d4ba948
commit
e9c9838cdc
|
@ -658,30 +658,11 @@ void ClientHandler::pool_downstream_connection(
|
||||||
<< " in group " << group;
|
<< " in group " << group;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &shared_addr = group->shared_addr;
|
|
||||||
|
|
||||||
if (shared_addr->affinity.type == SessionAffinity::NONE) {
|
|
||||||
auto &dconn_pool = group->shared_addr->dconn_pool;
|
|
||||||
dconn_pool.add_downstream_connection(std::move(dconn));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto addr = dconn->get_addr();
|
auto addr = dconn->get_addr();
|
||||||
auto &dconn_pool = addr->dconn_pool;
|
auto &dconn_pool = addr->dconn_pool;
|
||||||
dconn_pool->add_downstream_connection(std::move(dconn));
|
dconn_pool->add_downstream_connection(std::move(dconn));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientHandler::remove_downstream_connection(DownstreamConnection *dconn) {
|
|
||||||
if (LOG_ENABLED(INFO)) {
|
|
||||||
CLOG(INFO, this) << "Removing downstream connection DCONN:" << dconn
|
|
||||||
<< " from pool";
|
|
||||||
}
|
|
||||||
auto &dconn_pool =
|
|
||||||
dconn->get_downstream_addr_group()->shared_addr->dconn_pool;
|
|
||||||
dconn_pool.remove_downstream_connection(dconn);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// Computes 32bits hash for session affinity for IP address |ip|.
|
// Computes 32bits hash for session affinity for IP address |ip|.
|
||||||
uint32_t compute_affinity_from_ip(const StringRef &ip) {
|
uint32_t compute_affinity_from_ip(const StringRef &ip) {
|
||||||
|
@ -1138,26 +1119,48 @@ ClientHandler::get_downstream_connection(int &err, Downstream *downstream,
|
||||||
return std::move(dconn);
|
return std::move(dconn);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &dconn_pool = shared_addr->dconn_pool;
|
auto end = shared_addr->next;
|
||||||
|
for (;;) {
|
||||||
|
auto addr = &shared_addr->addrs[shared_addr->next];
|
||||||
|
|
||||||
// pool connection must be HTTP/1.1 connection
|
if (addr->proto != Proto::HTTP1) {
|
||||||
auto dconn = dconn_pool.pop_downstream_connection();
|
if (++shared_addr->next >= shared_addr->addrs.size()) {
|
||||||
|
shared_addr->next = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (dconn) {
|
assert(end != shared_addr->next);
|
||||||
if (LOG_ENABLED(INFO)) {
|
|
||||||
CLOG(INFO, this) << "Reuse downstream connection DCONN:" << dconn.get()
|
continue;
|
||||||
<< " from pool";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (LOG_ENABLED(INFO)) {
|
|
||||||
CLOG(INFO, this) << "Downstream connection pool is empty."
|
|
||||||
<< " Create new one";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dconn = std::make_unique<HttpDownstreamConnection>(group, 0, conn_.loop,
|
// pool connection must be HTTP/1.1 connection
|
||||||
worker_);
|
auto dconn = addr->dconn_pool->pop_downstream_connection();
|
||||||
|
if (dconn) {
|
||||||
|
if (++shared_addr->next >= shared_addr->addrs.size()) {
|
||||||
|
shared_addr->next = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LOG_ENABLED(INFO)) {
|
||||||
|
CLOG(INFO, this) << "Reuse downstream connection DCONN:" << dconn.get()
|
||||||
|
<< " from pool";
|
||||||
|
}
|
||||||
|
|
||||||
|
dconn->set_client_handler(this);
|
||||||
|
|
||||||
|
return dconn;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (LOG_ENABLED(INFO)) {
|
||||||
|
CLOG(INFO, this) << "Downstream connection pool is empty."
|
||||||
|
<< " Create new one";
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dconn =
|
||||||
|
std::make_unique<HttpDownstreamConnection>(group, 0, conn_.loop, worker_);
|
||||||
|
|
||||||
dconn->set_client_handler(this);
|
dconn->set_client_handler(this);
|
||||||
|
|
||||||
return dconn;
|
return dconn;
|
||||||
|
|
|
@ -807,16 +807,6 @@ int HttpDownstreamConnection::end_upload_data() {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
void remove_from_pool(HttpDownstreamConnection *dconn) {
|
void remove_from_pool(HttpDownstreamConnection *dconn) {
|
||||||
auto &group = dconn->get_downstream_addr_group();
|
|
||||||
auto &shared_addr = group->shared_addr;
|
|
||||||
|
|
||||||
if (shared_addr->affinity.type == SessionAffinity::NONE) {
|
|
||||||
auto &dconn_pool =
|
|
||||||
dconn->get_downstream_addr_group()->shared_addr->dconn_pool;
|
|
||||||
dconn_pool.remove_downstream_connection(dconn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto addr = dconn->get_addr();
|
auto addr = dconn->get_addr();
|
||||||
auto &dconn_pool = addr->dconn_pool;
|
auto &dconn_pool = addr->dconn_pool;
|
||||||
dconn_pool->remove_downstream_connection(dconn);
|
dconn_pool->remove_downstream_connection(dconn);
|
||||||
|
|
|
@ -164,12 +164,6 @@ void Worker::replace_downstream_config(
|
||||||
g->retired = true;
|
g->retired = true;
|
||||||
|
|
||||||
auto &shared_addr = g->shared_addr;
|
auto &shared_addr = g->shared_addr;
|
||||||
|
|
||||||
if (shared_addr->affinity.type == SessionAffinity::NONE) {
|
|
||||||
shared_addr->dconn_pool.remove_all();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto &addr : shared_addr->addrs) {
|
for (auto &addr : shared_addr->addrs) {
|
||||||
addr.dconn_pool->remove_all();
|
addr.dconn_pool->remove_all();
|
||||||
}
|
}
|
||||||
|
@ -307,10 +301,8 @@ void Worker::replace_downstream_config(
|
||||||
std::shuffle(std::begin(shared_addr->addrs), std::end(shared_addr->addrs),
|
std::shuffle(std::begin(shared_addr->addrs), std::end(shared_addr->addrs),
|
||||||
randgen_);
|
randgen_);
|
||||||
|
|
||||||
if (shared_addr->affinity.type != SessionAffinity::NONE) {
|
for (auto &addr : shared_addr->addrs) {
|
||||||
for (auto &addr : shared_addr->addrs) {
|
addr.dconn_pool = std::make_unique<DownstreamConnectionPool>();
|
||||||
addr.dconn_pool = std::make_unique<DownstreamConnectionPool>();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dst->shared_addr = shared_addr;
|
dst->shared_addr = shared_addr;
|
||||||
|
|
|
@ -164,7 +164,6 @@ struct SharedDownstreamAddr {
|
||||||
// TODO Verify that this approach performs better in performance
|
// TODO Verify that this approach performs better in performance
|
||||||
// wise.
|
// wise.
|
||||||
DList<Http2Session> http2_avail_freelist;
|
DList<Http2Session> http2_avail_freelist;
|
||||||
DownstreamConnectionPool dconn_pool;
|
|
||||||
// Configuration for session affinity
|
// Configuration for session affinity
|
||||||
AffinityConfig affinity;
|
AffinityConfig affinity;
|
||||||
// Next http/1.1 downstream address index in addrs.
|
// Next http/1.1 downstream address index in addrs.
|
||||||
|
|
Loading…
Reference in New Issue