基于最近对 HTTP/2 的争论和它的优势, 是时候升级底层架构了这篇文章将会介绍如何在安装和配置 HAProxy 和 Ngnix(使用 ssl 终端)为了简化流程, 我建议你准备好使用 Docker 镜像
如果你想跳过安装环节或你只对配置环节感兴趣, 可以跳至配置部分
我为什么需要关注 HTTP/2?
这里有一些介绍 HTTP/2 益处的文章 - 而且我鼓励你去读一读下面我将重点介绍我认为比较重要的几点
HTTP/2 的主要优势:
使用二进制数据 (不像 HTTP/1.1 一样使用明文) 而且它使用了 header 数据压缩不用再为 header 和 cookie 的大小而担心了
它是完全多元化的, 为了提升并发性可以使用一个连接加载多种资源你的网站性能在需要引入多种资源的时候会表现得更好, 因为现在它们可以在一次 TCP 连接中全部加载, 在非阻塞模式中域名切分和资源级联变成了反面模式简单来说: 你的网站加载会更快
它允许服务器提前推送请求到客户端的缓存(目前 Ngnix 不支持这个特性)
它使用新的 ALPN 扩展, 那将允许更快地加密连接这个加密协议在初始化连接的阶段是可用的
今天我可以使用它吗?
是的, 你可以正如你所看到的在 Can I Use 上的服务那样, 所有现代浏览器现在都支持 HTTP/2, 这里包括 IE11 和 Edge 唯一的例外是移动端的 Opera Mini 和 Android 浏览器不支持它
此外, 下面描述的配置都会确保客户端在不支持 HTTP/2 的情况下, 退回到 HTTP/1.1 这非常重要: 你的网站应该为那些老版本浏览器或搜索引擎爬虫提供访问支持
安装
我会在 CentOS 7 下安装, 如果你使用其他 Linux 发布版本, 你可以简单调整下代码
你需要做的:
1. 站点能跑通 SSL 如果你还没有虚拟证书的话, 你需要使用虚拟证书(简单)
2.Ngnix 1.9.5 或更新版本( 简单 )
3. 安装配置好 OpenSSL 的 HAPorxy 1.6 或更新版( 需要一些技巧 )
4. 良好的 HAPRoxy 和 Ngnix 配置( 简单 )
5. 确认你是否已经在使用 HTTP/2,HTTP/2 and SPDY indicator 对 Chrome 友好
OpenSSL 部分是需要一些技巧, 因为大部分有 OpwnSSL 1.0.1(或者更旧的版本)的 Linux 分支都不支持 ALPN(应用层协议协商)ALPN 协议允许应用层去协商, 这个协议将被用在连接中, 而且这是基本的, 如果我们要在相同的 TCP 端口支持 HTTP/2 和 HTTP/1 除此之外, HTTP/2 在 HAProxy 中只支持使用 ALPN, 所以它一定会在我们的列表里
如果你对安装流程熟悉的话, 请直接跳至配置部分.
1. 获取 SSL 证书
你可以很便宜的从 ssl2buy.com 上买到信任证书, 那里有许多靠谱发行机构的代售我曾经在那里买了一堆证书而且我推荐他们的服务和客户支持你可以从那里拿到低于 20 美元的 AphaSSL 证书
如果你需要为 HAProxy 或 Nginx 生成虚拟证书, 你可以使用下面的命令:
我们需要在下一步的配置中使用生成的证书和秘钥
2.Nginx 安装
在 CentOS 7 上安装 Ngnix 1.9 十分简单唯一需要做的就是使用主线版 YUM 源, 而不是稳定版就像 Ngnix.org.oage 上描述的那样, 把 yum 源的配置放到 / etc/yum.repos.d/nginx.repo 位置然后执行 yum install:
搞定
让我们创建一个 Ngnix vhost.conf(虚拟主机配置文件)确保我们的 Nginx 在拥有 HTTP/2 的情况下正常工作下面是一个简单的 vhost 配置:
第一点: 关键点是在 listen 443 default_server ssl http2 那一行这就相当于你使用了 HTTP/2
第二点: 现在忽略第三行 listen 81 部分的配置 我们一会再回来看这部分
第三点: 我使用使用标准的 80/443 端口在 Docker 镜像里跑这个样例, 所以它们不会和我的 host 主机上的任何端口发生冲突如果有需要, 你可以把它调整至适用你的需要
第四点: 使用在获取 SSL 证书那一步生成的 dummy.crt 和 dummy.key
好了, 当你使用 https:// 协议连接站点时, HTTP/2 提示器会提示你站点正在运行 HTTP/2 协议
恭喜你, 你的 Ngnix 已经在运行 HTTP/2 了!
3. OpenSSL 和 HAProxy 安装
这一部分有点棘手我们需要编译 OpenSSL 1.0.2 的源码 (因为在 yum 中还没有可用的资源) 并且在之后的 HAProxy 重编译中还会使用到它
建立 OpenSSL 的工作, 我们使用 no-shared 参数, 并且 HAProxy 是通过静态方式连接到 OpenSSL 的我遵照的是 HAProxy 官方的 README 但可笑的是, 我最终还是采用了其他的方式并且要非常足智多谋你会常常去读这些冗长且乏味的 README 文件吗?
在那之后, 你应该已经编译通过 HAProxy 且安装好了测试一下:
haproxy -vv
4. 配置
这是一个我们将用到完整的 / etc/haproxy/haproxy.cfg(HAProxy 配置):
最本质的部分在这:
这里我们定义了 HTTPS 前端接口在客户端请求 HAProxy 时监听 443 端口
请求被后端的 nodes-http2 还是 nodes-http 处理取决于客户端是否支持 HTTP2. 注意我们决定 SSL 在 HAProxy 上使用这个配置, 连接对后端服务器来说是被解密过的我们的后端服务器可以被 HAProxy 用 web 服务器的域名访问(这就是运行过程中的 Nginx, 就像我们上面说的)
在 bind *:443 line with alpn h2,http/1.1 一行我们建议为了方便客户端使用最好两种协议 (HTTP/2 and HTTP/1.1) 都支持
这样的话浏览器即使不支持 HTTP/2, 也可以浏览我们的网站
use_backend nodes-http2 if { ssl_fc_alpn -i h2 } 支持 HTTP/2 的客户端会被重定向到 nodes-http2 后端节点, 剩下使用 HTTP/1.1 协议的将被 nodes-http 处理如果你想让后端兼容还不支持 HTTP/2 的客户端, 这件事十分重要的
因此我们会有下面这一行:
server node1 web.server:81 check send-proxy
在这里, 我们只讨论了 HAProxy 和 HTTP/2 协议通常它连接 web.server 在 81 端口我们还有更令人高兴的惊喜吗?
让我们用 nginx 下列虚拟主机配置(如上所述):
这一行: listen 81 default_server http2 proxy_protocol;
定义了服务器在端口 81, 会处理 HTTP/2 的请求请注意, 我们无法在服务器使用 443 端口进行 SSL 连接: SSL 连接已经被 HAProxy 解密过了, 所以现在我们有一个非加密连接因此我们需要限制服务器的 81 端口只使用 HTTP/2, 不使用 SSL
题外话: 小也有 proxy_protocol 关键词在 haproxy.cfg 等效发送代理, 在后端服务器配置代理协议是独立出来的, 这儿有篇文章很好的解释了原因简而言之, 它允许通过 HAProxy 后端服务器传送客户端的 IP 地址和端口号, 这通常是非常理想的
你可以使用上面的配置运行 HAProxy:
HAProxy F / etc / HAProxy / haproxy.cfg
现在你应该能够连接到您的代理主机(例如 https://localhost:443/), 看到它正在运行 HTTP / 2 如果你在 Firefox 的测试, 检查网络请求头的标题, 你会看到 X-Firefox-Spdy: h2
Docker images
如果你早已经会使用 Docker, 你可以用我们的 MILLION12 镜像当 Docker 还是 1.0 版本的时候我们已经开始使用 Docker 很长时间了(MILLION12 这是我们的仓库地址), 而且我们已经构建了一堆有用的镜像 在这个例子里, 我们将使用 million12/haproxy 和 million12/nginx 这两个镜像里面的配置是我们讨论后的最终结果
你可以运行整个栈通过使用 docker-compose.yml 文件注意我们是通过 haproxy 容器里的 web.server 主机名连接 Nignx 的, 那个域名就是当前 haproxy.cfg 使用的主机名
连接 https://haproxy:8443 你就会看到屏幕显示出如下内容(注意蓝色的 HTTP/2 提示部分)
如果你想看看使用这些 Docker 镜像和上述配置的真实的产品工程, 打开 https://PrototypeBrewery.ioPrototype Brewery 是我们的产品, 一个计划和构建交互式 web 项目的原型工具打开看看吧, 我们已经在使用 HTTP/2 了(别忘了注册)
总结
正如你看到的, 迁移到 HTTP/2 真的很简单, 你今天就能做掉 没有什么理由让你再等下去了, 主流浏览器都已经支持它了而且即使回迁到 HTTP/1.1 上你仍然是安全的
如果你认为我在这里漏写了什么, 或者还有什么可以改进的, 请在下面留言评论
来源: http://www.codeceo.com/haproxy-nginx-http2-guide.html