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:
Tatsuhiro Tsujikawa 2019-01-11 23:26:08 +09:00
parent 803d4ba948
commit e9c9838cdc
4 changed files with 38 additions and 54 deletions

View File

@ -658,30 +658,11 @@ void ClientHandler::pool_downstream_connection(
<< " 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 &dconn_pool = addr->dconn_pool;
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 {
// Computes 32bits hash for session affinity for IP address |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);
}
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
auto dconn = dconn_pool.pop_downstream_connection();
if (addr->proto != Proto::HTTP1) {
if (++shared_addr->next >= shared_addr->addrs.size()) {
shared_addr->next = 0;
}
if (dconn) {
if (LOG_ENABLED(INFO)) {
CLOG(INFO, this) << "Reuse downstream connection DCONN:" << dconn.get()
<< " from pool";
}
} else {
if (LOG_ENABLED(INFO)) {
CLOG(INFO, this) << "Downstream connection pool is empty."
<< " Create new one";
assert(end != shared_addr->next);
continue;
}
dconn = std::make_unique<HttpDownstreamConnection>(group, 0, conn_.loop,
worker_);
// pool connection must be HTTP/1.1 connection
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);
return dconn;

View File

@ -807,16 +807,6 @@ int HttpDownstreamConnection::end_upload_data() {
namespace {
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 &dconn_pool = addr->dconn_pool;
dconn_pool->remove_downstream_connection(dconn);

View File

@ -164,12 +164,6 @@ void Worker::replace_downstream_config(
g->retired = true;
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) {
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),
randgen_);
if (shared_addr->affinity.type != SessionAffinity::NONE) {
for (auto &addr : shared_addr->addrs) {
addr.dconn_pool = std::make_unique<DownstreamConnectionPool>();
}
for (auto &addr : shared_addr->addrs) {
addr.dconn_pool = std::make_unique<DownstreamConnectionPool>();
}
dst->shared_addr = shared_addr;

View File

@ -164,7 +164,6 @@ struct SharedDownstreamAddr {
// TODO Verify that this approach performs better in performance
// wise.
DList<Http2Session> http2_avail_freelist;
DownstreamConnectionPool dconn_pool;
// Configuration for session affinity
AffinityConfig affinity;
// Next http/1.1 downstream address index in addrs.