通过使用 HTTP/2 服务器推送,服务器可以发送多个资源以响应客户端请求,客户端无需明确请求每个资源,即,在客户端请求一个资源时预先发送相关的资源。它减少了等待每个请求提供资源而可能产生的延迟。
例如,一个网站包含三个资源:index.html、style.css 和 favicon.ico。假定一个用户通过浏览器连接到该网站的主页,并检索 index.html。在浏览器收到 index.html 后,它发现需要 style.css 和 favicon.ico。然后,浏览器发出请求以获取另外两个文件。因此,为了加载该网页,浏览器在逐渐发现该网站的组成部分时堆叠网络往返请求。
在使用 HTTP/2 推送时,服务器可以主动采取措施,以通过一些规则在特定时刻触发推送。例如,在服务器收到 index.html 请求时,它可以推送 style.css 和 favicon.ico,而无需等待来自浏览器的相应请求。如果正确完成,在浏览器完成 index.html 解析时,就已经在推送模式下开始传输 styles.css 和 script.js 了。
LINK
标头
可以使用预加载链接元素为客户端指定给定网页所需的外部资源。服务器还可以发送类型设置为预加载的 Link 标头。在处理最初请求的页面之前,客户端使用该标头请求资源。
Link: </style.css>; rel=preload; as=style
如果启用了服务器推送,NSX Advanced Load Balancer 可以拦截这些 Link 标头以创建 PUSH_PROMISE 帧并获取资源,客户端无需发出这些资源的请求。服务器还可以选择使用 nopush 目标属性指定不推送某些预加载链接元素:
Link: </styles.css>; rel=preload; as=style; nopush
PUSH_PROMISE
帧
服务器将该帧发送到浏览器以开始推送资源。所有服务器推送流是通过 PUSH_PROMISE 帧启动的。在实体发送 PUSH_PROMISE 帧时,它传达将描述的资源推送到客户端的意图,这些资源需要与请求推送的资源的响应数据一起传送。
不支持从服务器发送的 PUSH_PROMISE 帧。不过,如果启用了服务器推送,在从服务器收到链接标头时,NSX Advanced Load Balancer 将向客户端发送 PUSH_PROMISE 帧。
NSX Advanced Load Balancer 中的 HTTP/2 服务器推送的工作方式
下图解释了 NSX Advanced Load Balancer 中的服务器推送的工作方式。
客户端将请求发送到 NSX Advanced Load Balancer 以访问 /index.html。NSX Advanced Load Balancer 将请求发送到后端服务器。
在后端服务器响应 NSX Advanced Load Balancer 时,它拦截该响应并检查是否存在任何链接标头。如果存在链接标头并设置了预加载,则 NSX Advanced Load Balancer 将 PUSH_PROMISE 帧以及它从服务器收到的响应一起发送到客户端。请注意上图中的 PUSH_PROMISE 帧。
在将 PUSH_PROMISE 帧发送到客户端后,NSX Advanced Load Balancer 发送 GET 请求以提前获取资源。
在 NSX Advanced Load Balancer 收到服务器的响应后,它将响应发回到客户端。
即使后端连接是 HTTP/1.1,服务器推送也会正常工作。
配置 HTTP/2 服务器推送
使用以下命令启用服务器推送:
[admin:ctrl]: > configure applicationprofile System-HTTP [admin:ctrl]: applicationprofile> http_profile [admin:ctrl]: applicationprofile:http_profile> http2_profile [admin:ctrl]: applicationprofile:http_profile:http2_profile> enable_http2_server_push Overwriting the previously entered value for enable_http2_server_push [admin:ctrl]: applicationprofile:http_profile:http2_profile> save [admin:ctrl]: applicationprofile:http_profile> save [admin:ctrl]: applicationprofile> save
在启用 HTTP/2 服务器推送时,您可以定义必须提前获取的资源数量。该功能可以限制请求数量,以免客户端不堪重负。要定义客户端 HTTP/2 连接上的最大并发推送请求数,请执行以下步骤:
[admin:ctrl]: > configure applicationprofile System-HTTP [admin:ctrl]: applicationprofile> http_profile [admin:ctrl]: applicationprofile:http_profile> http2_profile [admin:ctrl]: applicationprofile:http_profile:http2_profile> max_http2_concurrent_pushes_per_connection 16 Overwriting the previously entered value for max_http2_concurrent_pushes_per_connection [admin:ctrl]: applicationprofile:http_profile:http2_profile> save [admin:ctrl]: applicationprofile:http_profile> save [admin:ctrl]: applicationprofile> save
在应用程序配置文件设置中还具有其他字段,即 max_http2_control_frames_per_connection
和 max_http2_concurrent_streams_per_connection
。如果这些值小于 max_http2_concurrent_pushes_per_connection
,则使用这些值限制推送流(资源)数量。
选择性服务器推送
您可以使用 HTTP 策略或 DataScript 在响应中添加 Link 标头,因为服务器推送是通过拦截 Link 标头完成的。这样,您就可以实现一种方法,以根据提供的匹配条件中满足的条件有选择地推送某些资源。
HTTP 响应策略示例如下所示:
HTTP/2 服务器推送和 NSX Advanced Load Balancer 缓存
如果要求是从缓存中获取一些资源,而不是 NSX Advanced Load Balancer 将新请求发送到后端服务器,则可以利用 NSX Advanced Load Balancer 缓存。
您可以利用 HTTP 缓存存储服务器响应和任何推送的资源。由于获取的资源也是发送 PUSH_PROMISE
帧后触发的服务器响应,因此,它们将作为单独的缓存对象存储在 HTTP 缓存中。在启用了 NSX Advanced Load Balancer 缓存的情况下,请求流程如下所示:
可见性和故障排除
应用程序日志:
标头:
HTTP 统计信息
admin:ctrl]: > show virtualservice vs_v2_to_v1 httpstats +---------------------------------+---------------------------------+ | Field | Value | +---------------------------------+---------------------------------+ | connections_handled | 16 | | requests_handled | 48 | | response_2xx | 44 | | response_3xx | 0 | | response_4xx | 2 | | response_5xx | 2 | | cache_hits | 12 | | cache_bytes | 184451 | | http2_requests_handled | 48 | | http2_response_2xx | 42 | | http2_response_3xx | 0 | | http2_response_4xx | 2 | | http2_response_5xx | 2 | | 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 | | http2_trailers_received | 0 | | http2_control_frame_flood_errors| 2 | | http2_queued_frames_flood_errors| 0 | | http2_empty_frame_flood_errors | 0 | | open_requests | 0 | | req_body_buffered_reqs | 0 | | resp_body_buffered_reqs | 0 | | invalid_httpv1_requests | 0 | | invalid_httpv2_requests | 0 | | dropped_requests | 0 | | server_push_requests_handled | 32 | | server_push_response_2xx | 28 | | server_push_response_3xx | 0 | | server_push_response_4xx | 2 | | server_push_response_5xx | 2 | +---------------------------------+---------------------------------+