HTTP2配置实战

4,644 阅读8分钟

本文讲述如何将自己的服务支持HTTP2。

HTTP1

HTTP1的问题

  1. 队头阻塞

    如果仅仅使用一个连接,它需要发起请求、等待响应,之后才能发起下一个请求。在请求应答过程中,如果出现任何状况,剩下所有的工作都会被阻塞在那次请求应答之后。这就是“队头阻塞”,它会阻碍网络传输和Web页面渲染,直至失去响应。为了防止这种问题,现代浏览器会针对单个域名开启6个连接,通过各个连接分别发送请求。它实现了某种程度上的并行,但是每个连接仍会受到“队头阻塞”的影响。

  2. 低效的TCP利用

    HTTP1并不支持多路复用,TCP协议保证连接都能正常工作,但是不能保证它们的性能是最优的。

  3. 臃肿的消息首部

    虽然h1提供了压缩被请求内容的机制,但是消息首部却无法压缩。

  4. 受限的优先级设置

    浏览器能指定优先级的方式是有限的:要么发起请求,要么不发起。浏览器为了先请求优先级高的资源,会推迟请求其他资源。但是优先级高的资源获取之后,在处理的过程中,浏览器并不会发起新的资源请求,所以服务器无法利用这段时间发送优先级低的资源,总的页面下载时间因此延长了。

  5. 第三方资源

    很多第三方资源都不在Web开发者的控制范围内,所以很可能其中有些资源的性能很差,会延迟甚至阻塞页面渲染。

HTTP1优化

基础不牢,地动山摇。为了优化HTTP1,开发人员们最大化的发挥了自己的聪明才智。

如Steve Souders这种大牛,写了《高性能网站建设指南》和姊妹篇《高性能网站建设进阶指南》,堪称Web性能科学的奠基之作。

开发人员们也想出了各种实用方案,经常使用的Web性能优化技术有:

  1. DNS查询优化
  2. 优化TCP连接(可以参考我的这篇文章TCP性能优化
  3. 避免重定向
  4. 客户端缓存
  5. 网络边缘的缓存
  6. 条件缓存
  7. 压缩和代码极简化
  8. 避免阻塞CSS/JS
  9. 图片优化

还有一些反模式的方案

  1. 生成精灵图和资源合并/内联
  2. 域名拆分
  3. 禁用cookie的域名

我们做这一切,不管多么麻烦多么艰辛,主要是为了优化性能,填HTTP1给我们埋的坑,虽然治标不治本。幸运的是,HTTP2来了。

HTTP2

HTTP2优点

  1. 二进制协议
    • HTTP/2采用二进制格式而非文本格式
    • 方便机器解析,但是肉眼识别起来比较困难
  2. HTTP/2是完全多路复用的,而非有序并阻塞的
    • 只需一个连接即可实现并行
    • 提升TCP连接的利用率
  3. 首部压缩
    • HTTP/2的首部被深度压缩
    • 显著减少传输中的冗余字节
  4. HTTP/2让服务器可以将响应主动“推送”到客户端缓存中

HTTP2部署

部署前

现在让我们看看没有升级前,www.asap2me.top/显示的结果

Chrome显示协议为http/1.1

部署

环境情况:

目前环境是:Centos7.6

Web服务:GoLang

Web服务端口号:8080

反向代理:Nginx

系统已经配置好Nginx,也支持HTTPS,关于如何安装Nginx和配置HTTPS可以参考HTTPS配置

部署分为两步:
  1. 获取并安装一个支持h2的Web服务器;
  2. 下载并安装一张TLS证书,让浏览器和服务器通过h2连接。申请TLS证书方法有

因为证书已经安装成功,这里主要讲解Nginx如何支持HTTP2。

Nginx支持HTTP2
  1. 查看当前模块/usr/local/nginx/sbin/nginx -V
    • configure arguments: --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
  2. 进入nginx源码包目录/home/work/nginx-1.12.0
  3. 重新编译,增加httpv2模块。 ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module
  4. make编译,这里不要进行 make install,否则就是覆盖安装。
    • 新生成的nginx存放位置在nginx源码下的objs下
    • 将原nginx做备份,将新nginx替换老nginx
  5. 修改nginx配置:listen 443 ssl http2;
  6. 重启nginx:sudo ./nginx -s reload (如果不生效就kill进程,重启nginx)
检查方法
  1. 直接使用curl请求
curl --http2 -v https://www.asap2me.top -k

2. 使用线上资源 myssl.com/http2_check…

  1. 谷歌浏览器直接请求

压力测试对比

使用HTTP2的性能未必会比HTTP1好,有时候也需要看业务场景。跟其他任何性能调优尝试一样,HTTP2可能也要经历编码、测试、分析以及优化的迭代过程。总体来说通过不断的优化,终会比HTTP1好。

HTTP1性能

使用ab对http1进行压力测试:

ab -k -c 10 -t 180 -n 10000 www.asap2me.top/

ab -k -c 10 -t 180 -n 10000 https://www.asap2me.top/
This is ApacheBench, Version 2.3 <$Revision: 1874286 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking www.asap2me.top (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests


Server Software:        nginx/1.12.0
Server Hostname:        www.asap2me.top
Server Port:            443
SSL/TLS Protocol:       TLSv1.2,ECDHE-RSA-AES128-GCM-SHA256,2048,128
Server Temp Key:        ECDH P-256 256 bits
TLS Server Name:        www.asap2me.top

Document Path:          /
Document Length:        12 bytes

Concurrency Level:      10
Time taken for tests:   30.967 seconds
Complete requests:      10000
Failed requests:        0
Keep-Alive requests:    9905
Total transferred:      1749525 bytes
HTML transferred:       120000 bytes
Requests per second:    322.93 [#/sec] (mean)
Time per request:       30.967 [ms] (mean)
Time per request:       3.097 [ms] (mean, across all concurrent requests)
Transfer rate:          55.17 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   9.5      0     121
Processing:    25   30   3.0     30     266
Waiting:       25   30   3.0     30     266
Total:         25   31  10.0     30     266

Percentage of the requests served within a certain time (ms)
  50%     30
  66%     30
  75%     31
  80%     31
  90%     32
  95%     33
  98%     35
  99%    115
 100%    266 (longest request)

HTTP2性能

使用h2load对HTTP2进行压力测试:

h2load -n 10000 -c 6 -T 180 www.asap2me.top/

h2load -n 10000 -c 10 -T 180 https://www.asap2me.top/
starting benchmark...
spawning thread #0: 10 total client(s). 10000 total requests
TLS Protocol: TLSv1.2
Cipher: ECDHE-RSA-AES128-GCM-SHA256
Server Temp Key: ECDH P-256 256 bits
Application protocol: h2
progress: 10% done
progress: 20% done
progress: 30% done
progress: 40% done
progress: 50% done
progress: 60% done
progress: 70% done
progress: 80% done
progress: 90% done
progress: 100% done

finished in 31.71s, 315.37 req/s, 27.74KB/s
requests: 10000 total, 10000 started, 10000 done, 10000 succeeded, 0 failed, 0 errored, 0 timeout
status codes: 10000 2xx, 0 3xx, 0 4xx, 0 5xx
traffic: 879.55KB (900660) total, 585.94KB (600000) headers (space savings 47.37%), 117.19KB (120000) data
                     min         max         mean         sd        +/- sd
time for request:    26.66ms    262.63ms     29.48ms      3.05ms    98.04%
time for connect:    97.46ms    106.95ms     99.53ms      3.16ms    80.00%
time to 1st byte:   127.59ms    141.29ms    130.75ms      4.77ms    80.00%
req/s           :      31.54       35.41       33.82        1.14    80.00%

HTTP1.1和HTTP2压测后,在总时间上差别不大,主要是因为测试的接口不合适。不过我们仍能看出,在机器CPU和流量上,HTTP2是有大幅提升的。

注意问题

将服务升级为支持HTTP2.0,需要考虑如下问题:

  1. 浏览器的支持情况:目前主流浏览器都支持h2,如果不支持,会自动退回到h1,所以问题不大。
  2. 迁移到TLS:服务器需要支持TLS 1.2或更高版本,以及一组特定的临时加密算法。因为大多数关注安全的现代网站已经被“TLS无处不在”的大潮所席卷,所以应该不成问题。
  3. 撤销针对HTTP/1.1的“优化”:这部分是工作量最大的一部分
  4. 第三方资源:第三方资源有可能会拖累HTTP/2带来的任何可能的性能优化,需要判断是否真的需要第三方资源。
  5. 支持旧版本客户端:需要确保TLS设置方式以及是否仍然能够支持HTTP/1,否则有用户可能彻底失去了通过h1访问网站的机会

插曲

写文章的过程中,突然报这个错误,还以为配置的问题,后来发现是需要注册。

大家如果在腾讯云买的域名,注册方法:icp-faq.dnspod.cn/why

总结

如果是新的服务,建议一开始就部署HTTP2,对于老的服务,也推荐升级为HTTP2。对于性能测试,推荐一个网站www.webpagetest.org/。

写博客是一个好事情,写完这个文章,至少又有几点值得写:

  1. HTTP2技术细节
  2. 多路复用的实现
  3. 服务端推送实现
  4. webpagetest使用

下一篇文章可以写写多路复用的具体实现。

资料

  1. HTTP2基础教程
  2. 为啥我的Chrome中看不到http请求的版本号?
  3. nginx配置支持http2
  4. nginx支持HTTP2的配置过程
  5. Nginx 支持Http2协议
  6. HTTP 2.0 PK HTTP 1.X —— 速度与激情
  7. ab命令压力测试
  8. h2load - HTTP/2 benchmarking tool - HOW-TO
  9. Web性能优化工具WebPageTest(一)——总览与配置

最后

大家如果喜欢我的文章,可以关注我的公众号(程序员麻辣烫)

我的个人博客为:shidawuhen.github.io/

往期文章回顾:

  1. Go语言
  2. MySQL/Redis
  3. 算法
  4. 架构/网络/项目
  5. 思考/读书笔记