Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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