Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions api/envoy/config/cluster/v3/circuit_breaker.proto
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,12 @@ message CircuitBreakers {

// The maximum number of pending requests that Envoy will allow to the
// upstream cluster. If not specified, the default is 1024.
// This limit is applied as a connection limit for non-HTTP traffic.
google.protobuf.UInt32Value max_pending_requests = 3;

// The maximum number of parallel requests that Envoy will make to the
// upstream cluster. If not specified, the default is 1024.
// This limit does not apply to non-HTTP traffic.
google.protobuf.UInt32Value max_requests = 4;

// The maximum number of parallel retries that Envoy will allow to the
Expand Down
1 change: 1 addition & 0 deletions docs/root/version_history/current.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Bug Fixes
* listener: fix a crash when updating any listener that does not bind to port.
* listener: listener add can reuse the listener socket of a draining filter chain listener and fix the request lost.
* mac: fix crash on startup on macOS 12 by changing the default allocator.
* tcp: fixed a bug where upstream circuit breakers applied HTTP per-request bounds to TCP connections.

Removed Config or Runtime
-------------------------
Expand Down
2 changes: 1 addition & 1 deletion source/common/conn_pool/conn_pool_base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ void ConnPoolImplBase::attachStreamToClient(Envoy::ConnectionPool::ActiveClient&
AttachContext& context) {
ASSERT(client.state() == Envoy::ConnectionPool::ActiveClient::State::READY);

if (!host_->cluster().resourceManager(priority_).requests().canCreate()) {
if (enforceMaxRequests() && !host_->cluster().resourceManager(priority_).requests().canCreate()) {
ENVOY_LOG(debug, "max streams overflow");
onPoolFailure(client.real_host_description_, absl::string_view(),
ConnectionPool::PoolFailureReason::Overflow, context);
Expand Down
4 changes: 4 additions & 0 deletions source/common/conn_pool/conn_pool_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,10 @@ class ConnPoolImplBase : protected Logger::Loggable<Logger::Id::pool> {
const Network::ConnectionSocket::OptionsSharedPtr socket_options_;
const Network::TransportSocketOptionsConstSharedPtr transport_socket_options_;

// True if the max requests circuit breakers apply.
// This will be false for the TCP pool, true otherwise.
virtual bool enforceMaxRequests() const { return true; }

std::list<Instance::IdleCb> idle_callbacks_;

// When calling purgePendingStreams, this list will be used to hold the streams we are about
Expand Down
1 change: 1 addition & 0 deletions source/common/tcp/conn_pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ class ConnPoolImpl : public Envoy::ConnectionPool::ConnPoolImplBase,
callbacks->onPoolFailure(reason, failure_reason, host_description);
}

bool enforceMaxRequests() const override { return false; }
// These two functions exist for testing parity between old and new Tcp Connection Pools.
virtual void onConnReleased(Envoy::ConnectionPool::ActiveClient&) {}
virtual void onConnDestroyed() {}
Expand Down
16 changes: 16 additions & 0 deletions test/integration/tcp_proxy_integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,24 @@ TEST_P(TcpProxyIntegrationTest, TcpProxyDownstreamDisconnect) {

TEST_P(TcpProxyIntegrationTest, TcpProxyManyConnections) {
autonomous_upstream_ = true;
config_helper_.addConfigModifier([&](envoy::config::bootstrap::v3::Bootstrap& bootstrap) -> void {
auto* static_resources = bootstrap.mutable_static_resources();
for (int i = 0; i < static_resources->clusters_size(); ++i) {
auto* cluster = static_resources->mutable_clusters(i);
auto* thresholds = cluster->mutable_circuit_breakers()->add_thresholds();
thresholds->mutable_max_connections()->set_value(1027);
thresholds->mutable_max_pending_requests()->set_value(1027);
}
});
initialize();
// The large number of connection is meant to regression test
// https://github.com/envoyproxy/envoy/issues/19033 but fails on apple CI
// TODO(alyssawilk) debug.
#if defined(__APPLE__)
const int num_connections = 50;
#else
const int num_connections = 1026;
#endif
std::vector<IntegrationTcpClientPtr> clients(num_connections);

for (int i = 0; i < num_connections; ++i) {
Expand Down