Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
3906abe
Added max_requests_connection for downstream connection.
Feb 4, 2021
ff52d2d
Moved max_requests_connection to core.v3.HttpProtocolOptions.
Feb 11, 2021
5fa29e3
Fixed format and release docs.
Feb 11, 2021
163c635
Undo deprecation.
Feb 11, 2021
3fecf7e
Fixed CI.
Feb 25, 2021
68301da
Merge remote-tracking branch 'upstream/main' into mx_rq_conn
Feb 25, 2021
236b9dc
Fix.
Feb 25, 2021
e46bd37
fix
Apr 1, 2021
6744578
Merge remote-tracking branch 'upstream/main' into mx_rq_conn
Apr 1, 2021
944e461
fix trailing whitespace
Apr 1, 2021
69b3990
fix.
Apr 8, 2021
aed45e3
fix
Jun 4, 2021
50fbcfb
Merge remote-tracking branch 'upstream/main' into mx_rq_conn
Jun 4, 2021
a34504e
Implemented for downstream.
Jun 4, 2021
cab8b98
fix format
Jun 4, 2021
a1b6593
fix docs
Jun 4, 2021
306227e
fix
Jun 4, 2021
f9f204d
fix comment
Jun 7, 2021
0a46515
added config test
Jun 7, 2021
8ed8e32
Merge remote-tracking branch 'upstream/main' into mx_rq_conn
Jun 7, 2021
c74bfd2
Honor old config
Jun 14, 2021
97988ae
Added test
Jun 15, 2021
7607d85
Merge remote-tracking branch 'upstream/main' into mx_rq_conn
Jun 15, 2021
a5ec9d8
fix integration test
Jun 23, 2021
c70c421
Merge remote-tracking branch 'upstream/main' into mx_rq_conn
Jun 23, 2021
86ff39e
fix ci
Jun 23, 2021
2418fd0
fix
Jun 23, 2021
310a0cc
fix
Jun 25, 2021
9926092
fix
Jun 25, 2021
bfa9cac
Added more test
Jun 29, 2021
5f9360e
fix
Jul 9, 2021
f53cf49
Merge remote-tracking branch 'upstream/main' into mx_rq_conn
Jul 9, 2021
6d80d9f
updated docs.
Jul 9, 2021
67d99a1
fix comments
Jul 14, 2021
bdc5c59
Merge remote-tracking branch 'upstream/main' into mx_rq_conn
Jul 14, 2021
83dd809
typos
Jul 14, 2021
5306bb1
Merge branch 'main' into mx_rq_conn
Jul 14, 2021
318096c
fix
Jul 14, 2021
f6989ee
added stat docs.
Jul 14, 2021
13d1358
fix
Jul 14, 2021
a1cd357
Updated comment
Jul 15, 2021
8a97141
Merge remote-tracking branch 'upstream/main' into mx_rq_conn
Jul 15, 2021
ee2bfd9
fix rst
Jul 15, 2021
ebf6747
Merge branch 'main' into mx_rq_conn
Jul 15, 2021
b34e753
fix comment
Jul 16, 2021
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
6 changes: 5 additions & 1 deletion api/envoy/config/cluster/v3/cluster.proto
Original file line number Diff line number Diff line change
Expand Up @@ -746,7 +746,11 @@ message Cluster {
// is respected by both the HTTP/1.1 and HTTP/2 connection pool
// implementations. If not specified, there is no limit. Setting this
// parameter to 1 will effectively disable keep alive.
google.protobuf.UInt32Value max_requests_per_connection = 9;
//
// .. attention::
// This field has been deprecated in favor of the :ref:`max_requests_per_connection <envoy_v3_api_field_config.core.v3.HttpProtocolOptions.max_requests_per_connection>` field.
google.protobuf.UInt32Value max_requests_per_connection = 9
[deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];

// Optional :ref:`circuit breaking <arch_overview_circuit_break>` for the cluster.
CircuitBreakers circuit_breakers = 10;
Expand Down
15 changes: 5 additions & 10 deletions api/envoy/config/cluster/v4alpha/cluster.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion api/envoy/config/core/v3/protocol.proto
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ message AlternateProtocolsCacheOptions {
google.protobuf.UInt32Value max_entries = 2 [(validate.rules).uint32 = {gt: 0}];
}

// [#next-free-field: 6]
// [#next-free-field: 7]
message HttpProtocolOptions {
option (udpa.annotations.versioning).previous_message_type =
"envoy.api.v2.core.HttpProtocolOptions";
Expand Down Expand Up @@ -157,6 +157,12 @@ message HttpProtocolOptions {
// If this setting is not specified, the value defaults to ALLOW.
// Note: upstream responses are not affected by this setting.
HeadersWithUnderscoresAction headers_with_underscores_action = 5;

// Optional maximum requests for both upstream and downstream connections.
// If not specified, there is no limit.
// Setting this parameter to 1 will effectively disable keep alive.
// For HTTP/2 and HTTP/3, due to concurrent stream processing, the limit is approximate.
google.protobuf.UInt32Value max_requests_per_connection = 6;
}

// [#next-free-field: 8]
Expand Down
8 changes: 7 additions & 1 deletion api/envoy/config/core/v4alpha/protocol.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/root/configuration/http/http_conn_man/stats.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ statistics:
downstream_cx_drain_close, Counter, Total connections closed due to draining
downstream_cx_idle_timeout, Counter, Total connections closed due to idle timeout
downstream_cx_max_duration_reached, Counter, Total connections closed due to max connection duration
downstream_cx_max_requests_reached, Counter, Total connections closed due to max requests per connection
downstream_cx_overload_disable_keepalive, Counter, Total connections for which HTTP 1.x keepalive has been disabled due to Envoy overload
downstream_flow_control_paused_reading_total, Counter, Total number of times reads were disabled due to flow control
downstream_flow_control_resumed_reading_total, Counter, Total number of times reads were enabled on the connection due to flow control
Expand Down
3 changes: 3 additions & 0 deletions docs/root/version_history/current.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@ Removed Config or Runtime
New Features
------------
* http: added :ref:`string_match <envoy_v3_api_field_config.route.v3.HeaderMatcher.string_match>` in the header matcher.
* http: added support for :ref:`max_requests_per_connection <envoy_v3_api_field_config.core.v3.HttpProtocolOptions.max_requests_per_connection>` for both upstream and downstream connections.

Deprecated
----------
* cluster: :ref:`max_requests_per_connection <envoy_v3_api_field_config.cluster.v3.Cluster.max_requests_per_connection>` is deprecated in favor of :ref:`max_requests_per_connection <envoy_v3_api_field_config.core.v3.HttpProtocolOptions.max_requests_per_connection>`.
* http: the HeaderMatcher fields :ref:`exact_match <envoy_v3_api_field_config.route.v3.HeaderMatcher.exact_match>`, :ref:`safe_regex_match <envoy_v3_api_field_config.route.v3.HeaderMatcher.safe_regex_match>`,
:ref:`prefix_match <envoy_v3_api_field_config.route.v3.HeaderMatcher.prefix_match>`, :ref:`suffix_match <envoy_v3_api_field_config.route.v3.HeaderMatcher.suffix_match>` and
:ref:`contains_match <envoy_v3_api_field_config.route.v3.HeaderMatcher.contains_match>` are deprecated by :ref:`string_match <envoy_v3_api_field_config.route.v3.HeaderMatcher.string_match>`.

6 changes: 5 additions & 1 deletion generated_api_shadow/envoy/config/cluster/v3/cluster.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion generated_api_shadow/envoy/config/core/v3/protocol.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions source/common/http/conn_manager_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ namespace Http {
COUNTER(downstream_cx_http3_total) \
COUNTER(downstream_cx_idle_timeout) \
COUNTER(downstream_cx_max_duration_reached) \
COUNTER(downstream_cx_max_requests_reached) \
COUNTER(downstream_cx_overload_disable_keepalive) \
COUNTER(downstream_cx_protocol_error) \
COUNTER(downstream_cx_rx_bytes_total) \
Expand Down Expand Up @@ -495,6 +496,10 @@ class ConnectionManagerConfig {
* header.
*/
virtual bool shouldStripTrailingHostDot() const PURE;
/**
* @return maximum requests for downstream.
*/
virtual uint64_t maxRequestsPerConnection() const PURE;
};
} // namespace Http
} // namespace Envoy
14 changes: 14 additions & 0 deletions source/common/http/conn_manager_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,20 @@ RequestDecoder& ConnectionManagerImpl::newStream(ResponseEncoder& response_encod
ActiveStreamPtr new_stream(new ActiveStream(*this, response_encoder.getStream().bufferLimit(),
std::move(downstream_request_account)));

accumulated_requests_++;
if (config_.maxRequestsPerConnection() > 0 &&
accumulated_requests_ >= config_.maxRequestsPerConnection()) {
if (codec_->protocol() < Protocol::Http2) {
new_stream->state_.saw_connection_close_ = true;
// Prevent erroneous debug log of closing due to incoming connection close header.
drain_state_ = DrainState::Closing;
} else {
startDrainSequence();
}
ENVOY_CONN_LOG(debug, "max requests per connection reached", read_callbacks_->connection());
stats_.named_.downstream_cx_max_requests_reached_.inc();
}

new_stream->state_.is_internally_created_ = is_internally_created;
new_stream->response_encoder_ = &response_encoder;
new_stream->response_encoder_->getStream().addCallbacks(*new_stream);
Expand Down
2 changes: 2 additions & 0 deletions source/common/http/conn_manager_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,8 @@ class ConnectionManagerImpl : Logger::Loggable<Logger::Id::http>,
// Hop by hop headers should always be cleared for Envoy-as-a-proxy but will
// not be for Envoy-mobile.
bool clear_hop_by_hop_response_headers_{true};
// The number of requests accumulated on the current connection.
uint64_t accumulated_requests_{};
};

} // namespace Http
Expand Down
11 changes: 9 additions & 2 deletions source/common/upstream/upstream_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -713,8 +713,9 @@ ClusterInfoImpl::ClusterInfoImpl(
extensionProtocolOptionsTyped<HttpProtocolOptionsConfigImpl>(
"envoy.extensions.upstreams.http.v3.HttpProtocolOptions"),
factory_context.messageValidationVisitor())),
max_requests_per_connection_(
PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, max_requests_per_connection, 0)),
max_requests_per_connection_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(
http_protocol_options_->common_http_protocol_options_, max_requests_per_connection,
config.max_requests_per_connection().value())),
max_response_headers_count_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(
http_protocol_options_->common_http_protocol_options_, max_headers_count,
runtime_.snapshot().getInteger(Http::MaxResponseHeadersCountOverrideKey,
Expand Down Expand Up @@ -767,6 +768,12 @@ ClusterInfoImpl::ClusterInfoImpl(
: absl::nullopt),
factory_context_(
std::make_unique<FactoryContextImpl>(*stats_scope_, runtime, factory_context)) {
if (config.has_max_requests_per_connection() &&
http_protocol_options_->common_http_protocol_options_.has_max_requests_per_connection()) {
throw EnvoyException("Only one of max_requests_per_connection from Cluster or "
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a test for this case

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

"HttpProtocolOptions can be specified");
}

switch (config.lb_policy()) {
case envoy::config::cluster::v3::Cluster::ROUND_ROBIN:
lb_type_ = LoadBalancerType::RoundRobin;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,9 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig(
config.common_http_protocol_options().headers_with_underscores_action()),
local_reply_(LocalReply::Factory::create(config.local_reply_config(), context)),
path_with_escaped_slashes_action_(getPathWithEscapedSlashesAction(config, context)),
strip_trailing_host_dot_(config.strip_trailing_host_dot()) {
strip_trailing_host_dot_(config.strip_trailing_host_dot()),
max_requests_per_connection_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(
config.common_http_protocol_options(), max_requests_per_connection, 0)) {
// If idle_timeout_ was not configured in common_http_protocol_options, use value in deprecated
// idle_timeout field.
// TODO(asraa): Remove when idle_timeout is removed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ class HttpConnectionManagerConfig : Logger::Loggable<Logger::Id::config>,
originalIpDetectionExtensions() const override {
return original_ip_detection_extensions_;
}
uint64_t maxRequestsPerConnection() const override { return max_requests_per_connection_; }

private:
enum class CodecType { HTTP1, HTTP2, HTTP3, AUTO };
Expand Down Expand Up @@ -311,6 +312,7 @@ class HttpConnectionManagerConfig : Logger::Loggable<Logger::Id::config>,
const envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager::
PathWithEscapedSlashesAction path_with_escaped_slashes_action_;
const bool strip_trailing_host_dot_;
const uint64_t max_requests_per_connection_;
};

/**
Expand Down
1 change: 1 addition & 0 deletions source/server/admin/admin.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ class AdminImpl : public Admin,
return runCallback(path_and_query, response_headers, response, filter);
};
}
uint64_t maxRequestsPerConnection() const override { return 0; }

private:
/**
Expand Down
1 change: 1 addition & 0 deletions test/common/http/conn_manager_impl_fuzz_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ class FuzzConfig : public ConnectionManagerConfig {
originalIpDetectionExtensions() const override {
return ip_detection_extensions_;
}
uint64_t maxRequestsPerConnection() const override { return 0; }

const envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager
config_;
Expand Down
1 change: 1 addition & 0 deletions test/common/http/conn_manager_impl_test_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ class HttpConnectionManagerImplTest : public testing::Test, public ConnectionMan
originalIpDetectionExtensions() const override {
return ip_detection_extensions_;
}
uint64_t maxRequestsPerConnection() const override { return 0; }

Envoy::Event::SimulatedTimeSystem test_time_;
NiceMock<Router::MockRouteConfigProvider> route_config_provider_;
Expand Down
32 changes: 32 additions & 0 deletions test/common/upstream/upstream_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3794,6 +3794,38 @@ TEST(HostPartitionTest, PartitionHostsImmediateFailureExcludeDisabled) {
EXPECT_EQ(hosts[2], update_hosts_params.excluded_hosts_per_locality->get()[1][0]);
}

TEST_F(ClusterInfoImplTest, MaxRequestsPerConnectionValidation) {
const std::string yaml = R"EOF(
name: cluster1
type: STRICT_DNS
lb_policy: ROUND_ROBIN
max_requests_per_connection: 3
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
common_http_protocol_options:
max_requests_per_connection: 3
use_downstream_protocol_config: {}
)EOF";

EXPECT_THROW_WITH_MESSAGE(makeCluster(yaml), EnvoyException,
"Only one of max_requests_per_connection from Cluster or "
"HttpProtocolOptions can be specified");
}

TEST_F(ClusterInfoImplTest, DeprecatedMaxRequestsPerConnection) {
const std::string yaml = R"EOF(
name: cluster1
type: STRICT_DNS
lb_policy: ROUND_ROBIN
max_requests_per_connection: 3
)EOF";

auto cluster = makeCluster(yaml);

EXPECT_EQ(3U, cluster->info()->maxRequestsPerConnection());
}

} // namespace
} // namespace Upstream
} // namespace Envoy
11 changes: 11 additions & 0 deletions test/config/utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1017,6 +1017,17 @@ void ConfigHelper::setConnectTimeout(std::chrono::milliseconds timeout) {
connect_timeout_set_ = true;
}

void ConfigHelper::setDownstreamMaxRequestsPerConnection(uint64_t max_requests_per_connection) {
addConfigModifier(
[max_requests_per_connection](
envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager&
hcm) {
hcm.mutable_common_http_protocol_options()
->mutable_max_requests_per_connection()
->set_value(max_requests_per_connection);
});
}

envoy::config::route::v3::VirtualHost
ConfigHelper::createVirtualHost(const char* domain, const char* prefix, const char* cluster) {
envoy::config::route::v3::VirtualHost virtual_host;
Expand Down
3 changes: 3 additions & 0 deletions test/config/utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ class ConfigHelper {
// Set the connect timeout on upstream connections.
void setConnectTimeout(std::chrono::milliseconds timeout);

// Set the max_requests_per_connection for downstream through the HttpConnectionManager.
void setDownstreamMaxRequestsPerConnection(uint64_t max_requests_per_connection);

envoy::config::route::v3::VirtualHost createVirtualHost(const char* host, const char* route = "/",
const char* cluster = "cluster_0");

Expand Down
Loading