Nginx request_time比HTTP / 2慢

我们运行nginx / 1.9.10作为前端服务器,多个应用程序服务器作为上游服务器。 我们使用普通的http,主要是https,并在最后的弱点切换到http / 2。

我们这样logging:

log_format custom '$host $server_port $request_time ' '$upstream_response_time $remote_addr ' '"$http2" $upstream_addr $time_iso8601 ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"'; 

我们突然看到了$ request_time和$ upstream_response_time之间的较大差异。 这里的区别很自然,因为$ request_time取决于用户networking,而upstream_response_time则不取决于用户networking。

所以通常情况下,只要$ upstream_response_time是稳定的,你不应该太在意$ request_time。

但我仍然想检查发生了什么,因为它使http / 2越来越差因此,我比较了https / 1.1和https / 2.0的平均响应时间

首先,我把所有的http / 1.1请求都封装起来,然后计算平均response_time和average upstream_time:

 grep ' 443 ' access.log|grep 'HTTP/1.1'|\ cut -d ' ' -f 3,4 | awk '{r+=$1; u+=$2} END {print r/NR; print u/NR}' 0.0139158 # average response time for https/1.1 0.00691421 # average upstream time for https/1.1 

现在我用https / 2.0做了同样的事情:

 grep ' 443 ' access.log|grep 'HTTP/2.0'| \ cut -d ' ' -f 3,4 | awk '{r+=$1; u+=$2} END {print r/NR; print u/NR}' 0.0828755 # average response time for https/1.1 0.00606643 # average upstream time for https/2.0 

正如你所看到的上游时间几乎相同,但http / 2的要求时间要慢7倍! 哇! 不是http / 2预计会更快?

现在我检查了这两个值之间差异很大的所有请求,几乎所有的前500名都是302的状态码

 grep ' 443 ' access.log | grep 'HTTP/1.1' | \ awk '{ if ( $3 != $4 && $4 != "-" ) { \ gsub(/\./,"",$3);gsub(/\./,"",$4); \ print $3-$4,$4,$6,$9,$11,$12 }}' | \ sort -n | tail -n 10000 | grep 'POST HTTP/1.1" 302' | wc -l 9008 # of 10000 (or 90%) request ordered by difference between # response and request time have status code 302 

所以90%的请求和上行时间差异最大的是状态码302.这很奇怪

在http / 2上更糟糕:

 grep ' 443 ' access.log | grep 'HTTP/2.0' | \ awk '{ if ( $3 != $4 && $4 != "-" ) { \ gsub(/\./,"",$3);gsub(/\./,"",$4); \ print $3-$4,$4,$6,$9,$11,$12 }}' | \ sort -n | tail -n 10000 | grep 'POST HTTP/2.0" 302' | wc -l 9790 # of 10000 (or 98%) request ordered by difference between # response and request time have status code 302 

所以这些请求中有98%是302状态。

为什么http / 2看起来比http / 1.1慢呢? 为什么参与请求的302个状态代码是上游的,响应时间极为不同(在HTTP / 1.1和HTTP / 2.0中)?

我非常喜欢这个任务,我分析了它。

我主要采取了这些资源:[ https://www.nginx.com/blog/nginx-1-9-5/ ] [ https://www.nginx.com/blog/http2-module-nginx/ ] [ https ://blog.cloudflare.com/introducing-http2/ ] [ https://http2.github.io/faq/ ]和这个PDF

你可能从Nginx.org http://nginx.org/en/download.html下载了nginx / 1.9.10。 请确认。 你从源头上build立它? 你有没有试过nginx / 1.9.12?

正如您在CloudFlare文章中所看到的那样,测量Average Page Load time HTTP / 2显然是赢家(至less在他们的网站上)。

 Access via HTTP Protocol Version Average Page Load time HTTP 1.x 9.07 sec. SPDY/3.1 7.06 sec. HTTP/2 4.27 sec. 

但是,在跟踪平均响应时间时,请查看Nginx.org上的第二篇文章。

HTTP / 2的下一个关键点是多路复用。 HTTP / 2不是通过多个连接将响应和请求作为单独的数据stream进行发送和接收,而是通过一个字节stream或一个数据stream对它们进行复用。 它为不同的请求和不同的响应分割数据,每个分片都有自己的标识符和它的大小字段,所以terminal可以确定哪个数据属于哪个请求。

这里的缺点是,由于每个数据块都有自己的标识,自己的字段,除了实际的数据外,还有一些元数据可以传输。 所以,它有一些开销。

http / 2套接字

其他问题可能与你的nginx设置有关,例如在服务器块内。