Skip to content

Commit deee3ef

Browse files
authored
Enforce Active Connection limits (#6754)
* Enforce Active Connection limits 1. Throttle connections when there's no room in active conn queue 2. Adjust manage_active_queue() to not fail when the conn is already in active queue 3. Return true for PluginVC (dummy connection) add_to_active_queue 4. Metrics for throttling 5. Allow to disable active connection tracking 6. Doc updates
1 parent 4575058 commit deee3ef

8 files changed

Lines changed: 56 additions & 6 deletions

File tree

doc/admin-guide/files/records.config.en.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,22 @@ Network
409409
handled. This should be tuned according to your memory size, and expected
410410
work load. If this is set to 0, the throttling logic is disabled.
411411

412+
.. ts:cv:: CONFIG proxy.config.net.max_connections_in INT 30000
413+
414+
The total number of client connections that the :program:`traffic_server`
415+
can handle simultaneously. This should be tuned according to your memory size,
416+
and expected work load (network, cpu etc). This limit includes both keepalive
417+
and active client connections that :program:`traffic_server` can handle at
418+
any given instant.
419+
420+
.. ts:cv:: CONFIG proxy.config.net.max_active_connections_in INT 10000
421+
422+
The total number of active client connections that the |TS| can handle
423+
simultaneously. This should be tuned according to your memory size,
424+
and expected work load (network, cpu etc). If this is set to 0, active
425+
connection tracking is disabled and active connections have no separate
426+
limit and the total connections follow `proxy.config.net.connections_throttle`
427+
412428
.. ts:cv:: CONFIG proxy.config.net.default_inactivity_timeout INT 86400
413429
:reloadable:
414430

doc/admin-guide/monitoring/statistics/core/network-io.en.rst

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,17 @@ Network I/O
6060
.. ts:stat:: global proxy.process.net.connections_currently_open integer
6161
:type: counter
6262

63+
.. ts:stat:: global proxy.process.net.connections_throttled_in integer
64+
:type: counter
65+
66+
.. ts:stat:: global proxy.process.net.connections_throttled_out integer
67+
:type: counter
68+
69+
.. ts:stat:: global proxy.process.net.max.active.connections_throttled_in integer
70+
:type: counter
71+
6372
.. ts:stat:: global proxy.process.net.default_inactivity_timeout_applied integer
64-
.. ts:stat:: global proxy.process.net.dynamic_keep_alive_timeout_in_count integer
73+
.. ts:stat:: global proxy.process.net.default_inactivity_timeout_count integer
6574
.. ts:stat:: global proxy.process.net.dynamic_keep_alive_timeout_in_total integer
6675
.. ts:stat:: global proxy.process.net.inactivity_cop_lock_acquire_failure integer
6776
.. ts:stat:: global proxy.process.net.net_handler_run integer

iocore/net/Net.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ register_net_stats()
140140
(int)net_connections_throttled_in_stat, RecRawStatSyncSum);
141141
RecRegisterRawStat(net_rsb, RECT_PROCESS, "proxy.process.net.connections_throttled_out", RECD_INT, RECP_PERSISTENT,
142142
(int)net_connections_throttled_out_stat, RecRawStatSyncSum);
143+
RecRegisterRawStat(net_rsb, RECT_PROCESS, "proxy.process.net.max.active.connections_throttled_in", RECD_INT, RECP_PERSISTENT,
144+
(int)net_connections_max_active_throttled_in_stat, RecRawStatSyncSum);
143145
}
144146

145147
void

iocore/net/P_Net.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ enum Net_Stats {
5757
net_tcp_accept_stat,
5858
net_connections_throttled_in_stat,
5959
net_connections_throttled_out_stat,
60+
net_connections_max_active_throttled_in_stat,
6061
Net_Stat_Count
6162
};
6263

iocore/net/UnixNet.cc

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,11 @@ NetHandler::manage_active_queue(bool ignore_queue_size = false)
562562
max_connections_per_thread_in, max_connections_active_per_thread_in, total_connections_in, active_queue_size,
563563
keep_alive_queue_size);
564564

565+
if (!max_connections_active_per_thread_in) {
566+
// active queue has no max
567+
return true;
568+
}
569+
565570
if (ignore_queue_size == false && max_connections_active_per_thread_in > active_queue_size) {
566571
return true;
567572
}
@@ -721,16 +726,22 @@ NetHandler::add_to_active_queue(NetEvent *ne)
721726
max_connections_per_thread_in, active_queue_size, keep_alive_queue_size);
722727
ink_assert(mutex->thread_holding == this_ethread());
723728

729+
bool active_queue_full = false;
730+
724731
// if active queue is over size then close inactive connections
725732
if (manage_active_queue() == false) {
726-
// there is no room left in the queue
727-
return false;
733+
active_queue_full = true;
728734
}
729735

730736
if (active_queue.in(ne)) {
731737
// already in the active queue, move the head
732738
active_queue.remove(ne);
733739
} else {
740+
if (active_queue_full) {
741+
// there is no room left in the queue
742+
NET_SUM_DYN_STAT(net_connections_max_active_throttled_in_stat, 1);
743+
return false;
744+
}
734745
// in the keep-alive queue or no queue, new to this queue
735746
remove_from_keep_alive_queue(ne);
736747
++active_queue_size;

proxy/PluginVC.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -926,7 +926,7 @@ bool
926926
PluginVC::add_to_active_queue()
927927
{
928928
// do nothing
929-
return false;
929+
return true;
930930
}
931931

932932
SOCKET

proxy/http/Http1ClientSession.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,12 @@ Http1ClientSession::new_transaction()
465465
return;
466466
}
467467

468+
if (!client_vc->add_to_active_queue()) {
469+
// no room in the active queue close the connection
470+
this->do_io_close();
471+
return;
472+
}
473+
468474
// Defensive programming, make sure nothing persists across
469475
// connection re-use
470476
half_close = false;
@@ -474,7 +480,6 @@ Http1ClientSession::new_transaction()
474480
trans.set_proxy_ssn(this);
475481
transact_count++;
476482

477-
client_vc->add_to_active_queue();
478483
trans.new_transaction(read_from_early_data > 0 ? true : false);
479484
}
480485

proxy/http2/Http2ConnectionState.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1153,6 +1153,13 @@ Http2ConnectionState::state_closed(int event, void *edata)
11531153
Http2Stream *
11541154
Http2ConnectionState::create_stream(Http2StreamId new_id, Http2Error &error)
11551155
{
1156+
// first check if we've hit the active connection limit
1157+
if (!ua_session->get_netvc()->add_to_active_queue()) {
1158+
error = Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_CONNECTION, Http2ErrorCode::HTTP2_ERROR_NO_ERROR,
1159+
"refused to create new stream, maxed out active connections");
1160+
return nullptr;
1161+
}
1162+
11561163
// In half_close state, TS doesn't create new stream. Because GOAWAY frame is sent to client
11571164
if (ua_session->get_half_close_local_flag()) {
11581165
error = Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_STREAM, Http2ErrorCode::HTTP2_ERROR_REFUSED_STREAM,
@@ -1226,7 +1233,6 @@ Http2ConnectionState::create_stream(Http2StreamId new_id, Http2Error &error)
12261233
new_stream->mutex = new_ProxyMutex();
12271234
new_stream->is_first_transaction_flag = get_stream_requests() == 0;
12281235
increment_stream_requests();
1229-
ua_session->get_netvc()->add_to_active_queue();
12301236

12311237
return new_stream;
12321238
}

0 commit comments

Comments
 (0)