Skip to content

Commit

Permalink
Add option to set http.max_requests_per_io_cycle (#53)
Browse files Browse the repository at this point in the history
  • Loading branch information
suniltheta authored Oct 13, 2023
1 parent 7f8fc87 commit 2386022
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ These environment variables offer controls for the bootstrap config generation f
|`ENVOY_ENABLE_TCP_POOL_IDLE_TIMEOUT` |<true &#124; false> |Controls whether the `idle_timeout` protocol options feature is enabled for TCP upstreams. If not configured the default `idle_timeout` is 10 minutes. Set this environment variable to `false` to disable `idle_timeout` option. |true |
|`ENVOY_SANITIZE_ORIGINAL_PATH` |<true &#124; false> |Controls whether to sanitize `x-envoy-original-path` coming from an untrusted users. Set this environment variable to `false` to not sanitize `x-envoy-original-path` header coming from untrusted users. |true |
|`ENVOY_ACTIVE_HEALTH_CHECK_UNEJECT_HOST` |<true &#124; false> |Controls whether, if active HC is enabled and a host is ejected by outlier detection, a successful active health check unejects the host and consider it healthy. This also clears all the outlier detection counters. |false |
|`MAX_REQUESTS_PER_IO_CYCLE` |1 |For setting the limit on the number of HTTP requests processed from a single connection in a single I/O cycle. Requests over this limit are processed in subsequent I/O cycles. This mitigates CPU starvation by connections that simultaneously send high number of requests by allowing requests from other connections to make progress. This runtime value can be set to 1 in the presence of abusive HTTP/2 or HTTP/3 connections. By default this is not set. | |
|`APPMESH_SDS_SOCKET_PATH` |/path/to/socket |Unix Domain Socket for SDS Based TLS. | |
|`APPMESH_PREVIEW` |<0 &#124; 1> |Enables the App Mesh Preview Endpoint | |
|`APPMESH_DUALSTACK_ENDPOINT` |<0 &#124; 1> |Enables the App Mesh Dual-Stack Endpoint | |
Expand Down
20 changes: 18 additions & 2 deletions agent/envoy_bootstrap/envoy_bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ func getRuntimeConfigLayer0() (map[string]interface{}, error) {
return nil, err
}

return map[string]interface{}{
// ====== Runtime config with defaults set ======
result := map[string]interface{}{
// Allow all deprecated features to be enabled by Envoy. This prevents warnings or hard errors when
// it is sent config that is being deprecated.
"envoy.features.enable_all_deprecated_features": true,
Expand Down Expand Up @@ -180,7 +181,22 @@ func getRuntimeConfigLayer0() (map[string]interface{}, error) {
// This also clears all the outlier detection counters. To enable the new behavior, set Envoy env variable
// ENVOY_ACTIVE_HEALTH_CHECK_UNEJECT_HOST to `true`.
"envoy.reloadable_features.successful_active_health_check_uneject_host": setActiveHealthCheckUnejectHost,
}, nil
}

// ====== Runtime config with no defaults set ======
// Not set by Default
// http: Add runtime flag http.max_requests_per_io_cycle for setting the limit on the number of HTTP requests processed
// from a single connection in a single I/O cycle. Requests over this limit are processed in subsequent I/O cycles.
// This mitigates CPU starvation by connections that simultaneously send high number of requests by allowing requests
// from other connections to make progress. This runtime value can be set to 1 in the presence of abusive HTTP/2 or HTTP/3
// connections. By default this limit is disabled.
if maxRequestsPerIoCycle, err := env.OrInt("MAX_REQUESTS_PER_IO_CYCLE", -1); err != nil {
return nil, err
} else if maxRequestsPerIoCycle > 0 {
result["http.max_requests_per_io_cycle"] = maxRequestsPerIoCycle
}

return result, nil
}

func getMeshResourceFromNodeId(nodeId string) (*mesh_resource.MeshResource, error) {
Expand Down
52 changes: 52 additions & 0 deletions agent/envoy_bootstrap/envoy_bootstrap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,8 @@ func TestBuildNodeMetadata_StaticRuntimeMappingDefaultOverridden(t *testing.T) {
defer os.Unsetenv("ENVOY_SANITIZE_ORIGINAL_PATH")
os.Setenv("ENVOY_ACTIVE_HEALTH_CHECK_UNEJECT_HOST", "true")
defer os.Unsetenv("ENVOY_ACTIVE_HEALTH_CHECK_UNEJECT_HOST")
os.Setenv("MAX_REQUESTS_PER_IO_CYCLE", "1")
defer os.Unsetenv("MAX_REQUESTS_PER_IO_CYCLE")
metadata, err := buildMetadataForNode()
assert.Nil(t, err)
// ignore metadata: aws.appmesh.platformInfo & aws.appmesh.task.interfaces
Expand All @@ -707,6 +709,7 @@ metadata:
envoy.reloadable_features.sanitize_original_path: false
envoy.reloadable_features.successful_active_health_check_uneject_host: true
re2.max_program_size.error_level: 1000
http.max_requests_per_io_cycle: 1
`)
}

Expand Down Expand Up @@ -852,6 +855,55 @@ layers:
`)
}

func TestBuildLayeredRuntime_MaxRequestsPerIoCycleSet(t *testing.T) {
setup()
os.Setenv("MAX_REQUESTS_PER_IO_CYCLE", "1")
defer os.Unsetenv("MAX_REQUESTS_PER_IO_CYCLE")
rt, err := buildLayeredRuntime()
if err != nil {
t.Error(err)
}
checkMessage(t, rt, `
layers:
- name: "static_layer_0"
staticLayer:
envoy.features.enable_all_deprecated_features: true
envoy.reloadable_features.http_set_tracing_decision_in_request_id: true
envoy.reloadable_features.no_extension_lookup_by_name: true
envoy.reloadable_features.tcp_pool_idle_timeout: true
envoy.reloadable_features.sanitize_original_path: true
envoy.reloadable_features.successful_active_health_check_uneject_host: false
re2.max_program_size.error_level: 1000
http.max_requests_per_io_cycle: 1
- name: "admin_layer"
adminLayer: {}
`)
}

func TestBuildLayeredRuntime_MaxRequestsPerIoCycleNegative(t *testing.T) {
setup()
os.Setenv("MAX_REQUESTS_PER_IO_CYCLE", "-1")
defer os.Unsetenv("MAX_REQUESTS_PER_IO_CYCLE")
rt, err := buildLayeredRuntime()
if err != nil {
t.Error(err)
}
checkMessage(t, rt, `
layers:
- name: "static_layer_0"
staticLayer:
envoy.features.enable_all_deprecated_features: true
envoy.reloadable_features.http_set_tracing_decision_in_request_id: true
envoy.reloadable_features.no_extension_lookup_by_name: true
envoy.reloadable_features.tcp_pool_idle_timeout: true
envoy.reloadable_features.sanitize_original_path: true
envoy.reloadable_features.successful_active_health_check_uneject_host: false
re2.max_program_size.error_level: 1000
- name: "admin_layer"
adminLayer: {}
`)
}

func TestBuildClusterManager(t *testing.T) {
setup()
checkMessage(t, buildClusterManager(), `
Expand Down

0 comments on commit 2386022

Please sign in to comment.