HTTP/2 Support on Avi Vantage
Overview
HTTP/2 is the latest version of HTTP and developed over HTTP 1.1. HTTP/2 was originally named as HTTP/2.0. HTTP/2 is a binary protocol, while HTTP 1.1 is a text protocol.
The followings are the benefits of HTTP/2 over HTTP/1.1:
- Request and Response Multiplexing – With HTTP/1.1,for multiple parallel requests, multiple TCP connections are opened. With HTTP/2, multiple requests can be broken into frames that can be interleaved; the remote end is capable of reassembling them. Multiple connections can still be opened, but the number of connections is not as many as in HTTP/1.1.
- Server Push – It allows a server to send multiple resources in response to a client request without the client explicitly sending a request for each of these resources. This reduces latency otherwise introduced by waiting for each request to serve the resource. In HTTP/1.1, applications try to work around this by inlining the resource. HTTP/2 enables the client to cache the resource, to reuse it across pages, and to use multiplexing along with other resources.
- Flow control – HTTP/2 provides flow control at the application layer level by not allowing anyone end to overwhelm the other side, by using window sizes.
- Header Compression – In HTTP/1.1, each header in the request is sent as text. In HTTP/2, the header compresses request and response header metadata using the HPACK compression format, reducing the transmitted header size.
- Stream Prioritization – Since the HTTP messages are sent as frames and the frames from different streams can be interleaved, HTTP/2 can specify priorities for streams; all frames received can be accordingly prioritized based on their stream priorities.
Use Cases
- Workarounds used for HTTP 1.1, to make browsers compatible with HTTP/2, are no longer required.
- All the browsers which use HTTP/2 can be now be deployed on Avi Vantage.
- Support for the application using reverse proxy for gRPC.
Supported methods and modes for HTTP/2 on Avi Vantage
-
HTTP over TLS or HTTP over SSL:
Avi Vantage supports HTTP over TLS, or HTTP over SSL method for all HTTP/2 requests. This method uses TLS version 1.2 or later. -
All settings and options available for HTTP Setting are also available for HTTP/2-enabled virtual services. HTTP features, for example, HTTP policy, DataScripts, HTTP-timeout setting, etc. are supported for HTTP/2 requests as well.
HTTP/2 Support for Virtual Service, Pool and Pool Groups
Starting with Avi Vantage release 20.1, HTTP/2 is supported for server-side (back-end) connections too. For the releases prior to Avi Vantage 20.1:
- Avi Vantage supports HTTP/2 only for the front-end SSL enabled port.
- For the back-end connections, only HTTP/1.1 and 1.0 are supported.
The followings enhancements are available now for HTTP/2:
- For the front-end traffic, HTTP/2 is supported on both non-SSL and SSL enabled ports.
- For the back-end traffic, HTTP/2 is enabled at the pool level.
Enabling HTTP/2 on Virtual Service and Pools
Starting with Avi Vantage release 20.1, the HTTP/2 configuration option is no longer available through the application profile. The option is available through virtual service configuration.
The following configuration changes have been introduced to support HTTP/2 on the front-end and the back-end.
- The
http2_enabled
flag is deprecated from the application profile. - An
enable_http2
flag is available for the virtual service. - The
enable_http2
flag is available for the pool and pool group level to indicate that all the servers configured under this pool are HTTP/2.0 servers.
Configuring HTTP/2 using Avi UI
Navigate to Applications > Virtual Services, use the existing virtual service or create a new one. Select the checkbox for HTTP2 available under Settings > Service Ports. HTTP2 can be enabled for SSL and non-SSL ports as required.
Enable HTTP2 for the pools and the pool groups associated with the virtual service. Navigate to Applications > Pools and click on Create Pool or use the existing one. Select the Enable HTTP2 checkbox available under Servers as shown below.
For enabling HTTP2 for pool groups, select the checkbox for Enable HTTP2 available under Pool Servers as shown below.
Configuring HTTP/2 using Avi CLI
Use the enable_http2
flag from the configuration virtual service mode.
Configuring Virtual Service
[admin:controller]: > configure virtualservice http2_vs
[admin:controller]: virtualservice> services index 1
[admin:controller]: virtualservice:services> enable_http2
Similarly, Use the enable_http2
flag for the associated pool and pool groups for the virtual service.
Configuring Pool
[admin:controller]: > configure pool v2-pool
[admin:controller]: pool> enable_http2
Configuring Pool group
Use the following steps to enable HTTP/2 for a pool group.
[admin:controller]: > configure poolgroup v2-pg
[admin:controller]: poolgroup> enable_http2
Enabling HTTP/2 for Existing Pool Groups Follow the steps mentioned below to enable HTTP/2 for an existing pool group:
- Remove all the pool members from the pool groups.
- Configure
enable_http2
for all the pools using the steps mentioned above. - Configure
enable_http2
for the pool group. - Add all the pools to pool group.
Checking Status
The show virtualservice <virtual service name> will exhibit the flag value set as true as shown below.
[admin:controller]: > show virtualservice http2-vs
+------------------------------------+-----------------------------------------------------+
| Field | Value |
+------------------------------------+-----------------------------------------------------+
| uuid | virtualservice-2d67f7ed-eeee-4b81-af01-78ded84f4352 |
| name | http2-vs |
| enabled | True |
| services[1] | |
| port | 80 |
| enable_ssl | False |
| port_range_end | 80 |
| enable_http2 | True |<----
| services[2] | |
| port | 443 |
| enable_ssl | True |
| port_range_end | 443 |<----
| eable_http2 | True |
| application_profile_ref | applicationprofile-22 |
| network_profile_ref | System-TCP-Proxy |
| pool_ref | v2-pool |
| se_group_ref | Default-Group |
| http_policies[1] | |
| index | 11 |
| http_policy_set_ref | http_request_policy_1 |
+------------------------------------+-----------------------------------------------------+
[admin:controller]: > show pool v2-pool
+---------------------------------------+------------------------------------------------+
| Field | Value |
+---------------------------------------+------------------------------------------------+
| uuid | pool-5f38c27f-ff10-48e1-88e2-a9a2b39ad198 |
| name | v2-pool |
| default_server_port | 80 |
| graceful_disable_timeout | 1 min |
| connection_ramp_duration | 10 min |
| max_concurrent_connections_per_server | 0 |
| servers[1] | |
| ip | 10.90.103.72 |
| port | 80 |
| hostname | 10.90.103.72 |
| enabled | True |
| ratio | 1 |
| verify_network | False |
| resolve_server_by_dns | False |
| static | False |
| rewrite_host_header | False |
| lb_algorithm | LB_ALGORITHM_LEAST_CONNECTIONS |
| lb_algorithm_hash | LB_ALGORITHM_CONSISTENT_HASH_SOURCE_IP_ADDRESS |
| inline_health_monitor | True |
| use_service_port | False |
| capacity_estimation | False |
| capacity_estimation_ttfb_thresh | 0 milliseconds |
| vrf_ref | global |
| fewest_tasks_feedback_delay | 10 sec |
| enabled | True |
| request_queue_enabled | False |
| request_queue_depth | 128 |
| host_check_enabled | False |
| sni_enabled | True |
| rewrite_host_header_to_sni | False |
| rewrite_host_header_to_server_name | False |
| lb_algorithm_core_nonaffinity | 2 |
| lookup_server_by_name | False |
| analytics_profile_ref | System-Analytics-Profile |
| tenant_ref | admin |
| cloud_ref | Default-Cloud |
| server_timeout | 0 milliseconds |
| delete_server_on_dns_refresh | True |
| enable_http2 | True | <-----
+---------------------------------------+------------------------------------------------+
Limitations
- Caching is not supported for HTTP/2 pool in this release.
- HTTP/2 Connection multiplexing on upstream is not supported yet.
- HTTP/2 health monitor support is not available presently. If the back-end server only supports HTTP/2, HTTP(S) health monitor will not work for this pool. Only TCP or PING health monitor should be configured for this pool.
- If the back-end server is SSL-enabled and supports both HTTP/1 and HTTP/2, HTTPS health monitor should be configured with its own attribute.
- For non-SSL enabled port, HTTP/1.1 to HTTP/2.0 upgrade is not supported.
- The client should be aware of that this non-SSL port can only support HTTP/2.
- The back-end pool assumes that servers listening on the configured port only support HTTP/2 and will not send an HTTP1.1 to HTTP/2.0 upgrade.
- For the pool group, the HTTP version must be matched between the pool group and all the associated pools.
- HTTP/1.1’s chunked transfer-encoding mechanism on one side (the front-end) and HTTP/2’s chunked mechanism on the other side (back-end) is not supported together. i.e. If chunking is present i.e. if stream mode, or partial buffer mode is required with chunk on one side and V2 chunk on another side, this method is not supported.
Upgrading to Avi Vantage Release 20.1.1
If HTTP/2 is enabled in the application profile for a virtual service listening on port 80 and 443, then after an upgrade to Avi Vantage release 20.1, HTTP/2 will be automatically enabled on the virtual service on port 443. HTTP/2 will not be enabled on port 80 which is non-SSL enabled port.
Additional Configuration Options for HTTP/2 Profile
Starting with Avi Vantage release 20.1.1, the HTTP/2 configuration fields have been moved to a sub-field under http_profile
called http2_profile.
The followings three fields have been added to the http2_profile
:
max_http2_requests_per_connection
– This value controls the maximum number of that can be sent over a client-side HTTP/2 connection. If the value is set to 0, this means an unlimited number of requests can be sent over an HTTP/2 client-side connection.max_http2_header_field
– This field controls the maximum size (in BYTES) of the compressed request header field. The limit applies equally to both name and value of the request header. The range varies from 1-8192 BYTES. The default value is 4096 BYTES.http2_initial_window_size
– This field controls the window size of the initial flow control in HTTP/2 streams. The value for this field ranges from 64-32768 KB. The default value for this field is 64KB.max_http2_control_frames_per_connection
– This field controls the number of control frames that client can send over an HTTP/2 connection. The value for this field ranges from 0 to 10000, and the default value is 1000. The zero value for this parameter indicates unlimited number of control frames can be sent on a client-side HTTP/2 connection.max_http2_queued_frames_to_client_per_connection
– This field controls the number of frames that can be queued waiting to be sent over a client-side HTTP/2 connection at any given time. The value for this field ranges from 0 to 10000, and the default value is 1000. The zero value for this parameter indicates unlimited frames can be queued on a client-side HTTP/2 connection.max_http2_empty_data_frames_per_connection
– This field controls the number of empty data frames that client can send over an HTTP/2 connection. The value for this field ranges from 0 to 10000, and the default value is 1000. The zero value for this parameter indicates unlimited empty data frames over a client-side HTTP/2 connection.max_http2_concurrent_streams_per_connection
– This field is to configure the maximum number of concurrent streams over a client-side HTTP/2 connection. The value for this field ranges from 1 to 256, and the default value is 128.
The below CLI snippets exhibit configuration samples for the options mentioned above.
Login to the Avi CLI and use the applicationprofile
mode, and then the http2_profile
option to change the values of the parameters mentioned above.
[admin:controller]: > configure applicationprofile ap-1
Updating an existing object. Currently, the object is:
+------------------------------------------------------+---------------------------------------------------------+
| Field | Value |
+------------------------------------------------------+---------------------------------------------------------+
| uuid | applicationprofile-1d264f41-d19c-445e-a4df-740dca5957f0 |
| name | ap-1 |
| type | APPLICATION_PROFILE_TYPE_HTTP |
| http_profile | |
| connection_multiplexing_enabled | True |
| xff_enabled | True |
| xff_alternate_name | X-Forwarded-For |
| hsts_enabled | False |
| hsts_max_age | 365 |
| secure_cookie_enabled | False |
| httponly_enabled | False |
| http_to_https | False |
| server_side_redirect_to_https | False |
| x_forwarded_proto_enabled | False |
| post_accept_timeout | 30000 milliseconds |
| client_header_timeout | 10000 milliseconds |
| client_body_timeout | 30000 milliseconds |
| keepalive_timeout | 30000 milliseconds |
| client_max_header_size | 12 kb |
| client_max_request_size | 48 kb |
| client_max_body_size | 0 kb |
| max_rps_unknown_uri | 0 |
| max_rps_cip | 0 |
| max_rps_uri | 0 |
| max_rps_cip_uri | 0 |
| ssl_client_certificate_mode | SSL_CLIENT_CERTIFICATE_NONE |
| websockets_enabled | True |
| max_rps_unknown_cip | 0 |
| max_bad_rps_cip | 0 |
| max_bad_rps_uri | 0 |
| max_bad_rps_cip_uri | 0 |
| keepalive_header | False |
| use_app_keepalive_timeout | False |
| allow_dots_in_header_name | False |
| disable_keepalive_posts_msie6 | True |
| enable_request_body_buffering | False |
| enable_fire_and_forget | False |
| max_response_headers_size | 48 kb |
| respond_with_100_continue | True |
| hsts_subdomains_enabled | True |
| enable_request_body_metrics | False |
| fwd_close_hdr_for_bound_connections | True |
| max_keepalive_requests | 100 |
| disable_sni_hostname_check | False |
| reset_conn_http_on_ssl_port | False |
| http_upstream_buffer_size | 0 kb |
| enable_chunk_merge | True |
| http2_profile | |
| max_http2_control_frames_per_connection | 1000 |
| max_http2_queued_frames_to_client_per_connection | 1000 |
| max_http2_empty_data_frames_per_connection | 1000 |
| max_http2_concurrent_streams_per_connection | 128 |
| max_http2_requests_per_connection | 1000 |
| max_http2_header_field_size | 4096 bytes |
| http2_initial_window_size | 64 kb |
| preserve_client_ip | False |
| preserve_client_port | False |
| preserve_dest_ip_port | False |
| tenant_ref | admin |
+------------------------------------------------------+---------------------------------------------------------+
[admin:controller]: applicationprofile> http_profile
[admin:controller]: applicationprofile:http_profile> http2_profile
[admin:controller]: applicationprofile:http_profile:http2_profile> max_http2_control_frames_per_connection 2000
Overwriting the previously entered value for max_http2_control_frames_per_connection
[admin:controller]: applicationprofile:http_profile:http2_profile> max_http2_queued_frames_per_connection 2000
No command or arguments found in 'max_http2_queued_frames_per_connection 2000'.
[admin:controller]: applicationprofile:http_profile:http2_profile> max_http2_queued_frames_to_client_per_connection 2000
Overwriting the previously entered value for max_http2_queued_frames_to_client_per_connection
[admin:controller]: applicationprofile:http_profile:http2_profile> max_http2_concurrent_streams_per_connection 256
Overwriting the previously entered value for max_http2_concurrent_streams_per_connection
[admin:controller]: applicationprofile:http_profile:http2_profile> max_http2_requests_per_connection 2500
Overwriting the previously entered value for max_http2_requests_per_connection
[admin:controller]: applicationprofile:http_profile:http2_profile> http2_initial_window_size 256
Overwriting the previously entered value for http2_initial_window_size
[admin:controller]: applicationprofile:http_profile:http2_profile> max_http2_header_field_size 8192
Overwriting the previously entered value for max_http2_header_field_size
[admin:controller]: applicationprofile:http_profile:http2_profile> save
[admin:controller]: applicationprofile:http_profile> save
[admin:controller]: applicationprofile> save
+------------------------------------------------------+---------------------------------------------------------+
| Field | Value |
+------------------------------------------------------+---------------------------------------------------------+
| uuid | applicationprofile-1d264f41-d19c-445e-a4df-740dca5957f0 |
| name | ap-1 |
| type | APPLICATION_PROFILE_TYPE_HTTP |
| http_profile | |
| connection_multiplexing_enabled | True |
| xff_enabled | True |
| xff_alternate_name | X-Forwarded-For |
| hsts_enabled | False |
| hsts_max_age | 365 |
| secure_cookie_enabled | False |
| httponly_enabled | False |
| http_to_https | False |
| server_side_redirect_to_https | False |
| x_forwarded_proto_enabled | False |
| post_accept_timeout | 30000 milliseconds |
| client_header_timeout | 10000 milliseconds |
| client_body_timeout | 30000 milliseconds |
| keepalive_timeout | 30000 milliseconds |
| client_max_header_size | 12 kb |
| client_max_request_size | 48 kb |
| client_max_body_size | 0 kb |
| max_rps_unknown_uri | 0 |
| max_rps_cip | 0 |
| max_rps_uri | 0 |
| max_rps_cip_uri | 0 |
| ssl_client_certificate_mode | SSL_CLIENT_CERTIFICATE_NONE |
| websockets_enabled | True |
| max_rps_unknown_cip | 0 |
| max_bad_rps_cip | 0 |
| max_bad_rps_uri | 0 |
| max_bad_rps_cip_uri | 0 |
| keepalive_header | False |
| use_app_keepalive_timeout | False |
| allow_dots_in_header_name | False |
| disable_keepalive_posts_msie6 | True |
| enable_request_body_buffering | False |
| enable_fire_and_forget | False |
| max_response_headers_size | 48 kb |
| respond_with_100_continue | True |
| hsts_subdomains_enabled | True |
| enable_request_body_metrics | False |
| fwd_close_hdr_for_bound_connections | True |
| max_keepalive_requests | 100 |
| disable_sni_hostname_check | False |
| reset_conn_http_on_ssl_port | False |
| http_upstream_buffer_size | 0 kb |
| enable_chunk_merge | True |
| http2_profile | |
| max_http2_control_frames_per_connection | 2000 |
| max_http2_queued_frames_to_client_per_connection | 2000 |
| max_http2_empty_data_frames_per_connection | 1000 |
| max_http2_concurrent_streams_per_connection | 256 |
| max_http2_requests_per_connection | 2500 |
| max_http2_header_field_size | 8192 bytes |
| http2_initial_window_size | 256 kb |
| preserve_client_ip | False |
| preserve_client_port | False |
| preserve_dest_ip_port | False |
| tenant_ref | admin |
+------------------------------------------------------+---------------------------------------------------------+
[admin:controller]: >
[admin:controller]: > show applicationprofile ap-1
+------------------------------------------------------+---------------------------------------------------------+
| Field | Value |
+------------------------------------------------------+---------------------------------------------------------+
| uuid | applicationprofile-1d264f41-d19c-445e-a4df-740dca5957f0 |
| name | ap-1 |
| type | APPLICATION_PROFILE_TYPE_HTTP |
| http_profile | |
| connection_multiplexing_enabled | True |
| xff_enabled | True |
| xff_alternate_name | X-Forwarded-For |
| hsts_enabled | False |
| hsts_max_age | 365 |
| secure_cookie_enabled | False |
| httponly_enabled | False |
| http_to_https | False |
| server_side_redirect_to_https | False |
| x_forwarded_proto_enabled | False |
| post_accept_timeout | 30000 milliseconds |
| client_header_timeout | 10000 milliseconds |
| client_body_timeout | 30000 milliseconds |
| keepalive_timeout | 30000 milliseconds |
| client_max_header_size | 12 kb |
| client_max_request_size | 48 kb |
| client_max_body_size | 0 kb |
| max_rps_unknown_uri | 0 |
| max_rps_cip | 0 |
| max_rps_uri | 0 |
| max_rps_cip_uri | 0 |
| ssl_client_certificate_mode | SSL_CLIENT_CERTIFICATE_NONE |
| websockets_enabled | True |
| max_rps_unknown_cip | 0 |
| max_bad_rps_cip | 0 |
| max_bad_rps_uri | 0 |
| max_bad_rps_cip_uri | 0 |
| keepalive_header | False |
| use_app_keepalive_timeout | False |
| allow_dots_in_header_name | False |
| disable_keepalive_posts_msie6 | True |
| enable_request_body_buffering | False |
| enable_fire_and_forget | False |
| max_response_headers_size | 48 kb |
| respond_with_100_continue | True |
| hsts_subdomains_enabled | True |
| enable_request_body_metrics | False |
| fwd_close_hdr_for_bound_connections | True |
| max_keepalive_requests | 100 |
| disable_sni_hostname_check | False |
| reset_conn_http_on_ssl_port | False |
| http_upstream_buffer_size | 0 kb |
| enable_chunk_merge | True |
| http2_profile | |
| max_http2_control_frames_per_connection | 1000 |
| max_http2_queued_frames_to_client_per_connection | 1000 |
| max_http2_empty_data_frames_per_connection | 1000 |
| max_http2_concurrent_streams_per_connection | 128 |
| max_http2_requests_per_connection | 1000 |
| max_http2_header_field_size | 4096 bytes |
| http2_initial_window_size | 64 kb |
| preserve_client_ip | False |
| preserve_client_port | False |
| preserve_dest_ip_port | False |
| tenant_ref | admin |
+------------------------------------------------------+---------------------------------------------------------+
Logs
Cheking Logs Using Avi UI
Avi Vantage’s application logs display the HTTP version in the request as HTTP/2.0. Navigate to Applications > Virtual Services, select the desired virtual service, and navigate to Logs tab to check logs. In the below screenshot, Avi Vantage is exhibiting the GET method as HTTP/2.
Similarly, errors related to HTTP/2 requests and response can be checked under the Significant logs as well.
Checking Logs Using Avi CLI
The following are the few counters available for the HTTP/2 feature which can be used during troubleshooting.
- Request handled error
- Response codes (2xx, 3xx, 4xx, and 5xx)
- Protocol errors
- Flow-control error
- Frame size errors
- Compression errors
-
Refused Stream errors
-
Use the
show virtualservice <virtual service name> detail
command to check the available counters for the HTTP/2 method.[admin:controller]: > show virtualservice <virtual service name> detail | cache_bytes | 0 | | http2_requests_handled | 2 | | http2_response_2xx | 2 | | http2_response_3xx | 0 | | http2_response_4xx | 0 | | http2_response_5xx | 0 | | http2_protocol_errors | 0 | | http2_flow_control_errors | 0 | | http2_frame_size_errors | 0 | | http2_compression_errors | 0 | | http2_refused_stream_errors | 0 | | http2_enhance_your_calm | 0 | | http2_miscellaneous_errors | 0
-
Use the
show pool <pool name> detail
command to check HTTP/2-related errors in pool status.[admin:controller]: > show pool v2-pool detail | grep http2 | http2_protocol_header_errors | 0 | | http2_protocol_other_errors | 0 | | http2_flow_control_errors | 0 | | http2_frame_size_errors | 0 | | http2_compression_errors | 0 | | http2_refused_stream_errors | 0 | | http2_enhance_your_calm | 0 | | http2_misc_errors | 0 | [admin:controller]: