通过使用 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 中的服务器推送的工作方式。



  1. 客户端将请求发送到 NSX Advanced Load Balancer 以访问 /index.html。NSX Advanced Load Balancer 将请求发送到后端服务器。

  2. 在后端服务器响应 NSX Advanced Load Balancer 时,它拦截该响应并检查是否存在任何链接标头。如果存在链接标头并设置了预加载,则 NSX Advanced Load Balancer 将 PUSH_PROMISE 帧以及它从服务器收到的响应一起发送到客户端。请注意上图中的 PUSH_PROMISE 帧。

  3. 在将 PUSH_PROMISE 帧发送到客户端后,NSX Advanced Load Balancer 发送 GET 请求以提前获取资源。

  4. NSX Advanced Load Balancer 收到服务器的响应后,它将响应发回到客户端。

注:

即使后端连接是 HTTP/1.1,服务器推送也会正常工作。

配置 HTTP/2 服务器推送

  1. 使用以下命令启用服务器推送:

     [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 
  2. 在启用 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_connectionmax_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                               |
+---------------------------------+---------------------------------+