最近在复习 HTTP 协议的时候,突然想起来很早之前就对自己的项目进行过Nginx支持从 HTTP 1.1 -> SPDY 的升级。但是后来好像没成功就搁置了。
在复习的过程中看到过一篇文章,有提到 Nginx HTTP 1.1 -> HTTP 2.0 升级的一些前置需求,还给出了一些参考资料。这就挠得我心痒痒了,看完文章后赶紧的在把相关资料过一遍。发现其实这些资料也是较为大概的描述。
HTTP 2.0 是基于 HTTPS 的,而 HTTP 2.0 是 SPDY 的升级版也可以说是它的前身。最初设计还是支持明文的 HTTP,而 SPDY 则是强制使用 HTTPS,到后来 HTTP 2.0 也是强制使用了 HTTPS。(SPDY 到 HTTP 2.0 有一段历史,感兴趣的可以去查查。)
而真正需要开启 HTTP 2.0 模式,还是对一些前置要求明确的说明。
开启 HTTP 2.0 前置需求:
在此之前还是要说一下我的服务器情况:
系统:Ubuntu 14.04 x64
硬件:
可能你们看起来也不太高级,就是最普通的配置,但是以我目前使用的情况下来看,已经足够了。
废话不多,开始动手
nginx -V
输出如下信息:
nginx version: nginx/1.14.0 (Ubuntu)
built with OpenSSL 1.0.1f 11 Sep 2014
TLS SNI support enabled
configure arguments:……
这里可以看出 Nginx 的版本信息以及配置项等,虽然 Nginx 版本符合了,但是 OpenSSL 的版本却不符合即将要升级使用 HTTP 2.0 的前置条件。
那么怎么办呢?
先将 configure arguments 后的内容复制出来保留一下,稍后会用到。
然后要先把 OpenSSL 的版本升级了,只要大于 1.0.2 版本即可。
当然你可能想使用 update 的方式来实现 OpenSSL 的升级,但是很遗憾,我在尝试之后发现,并不能正常升级,我在查看源上的版本发现 1.0.1f 就是最高版本了。
OpenSSL 官方下载源:https://www.openssl.org/source/
OpenSSL Github:https://github.com/openssl/openssl
这里我以 1.1.1d 版本为例
wget https://www.openssl.org/source/openssl-1.1.1d.tar.gz
下载完成后解压该文件
tar -zxvf openssl-1.1.1d.tar.gz
进入解压后的文件夹
cd openssl-1.1.1d
使用 config 来对 OpenSSL 进行安装配置,配置文档以及压缩模块
./config shared zlib
接下来就可以尝试编译了
make
当然在此环节的时候,并没想象中顺利,因为我碰到了三种不同的错误:
第一次错误:
> ./config shared zlib
----- 这里顺利 -----
> make
……
……
……
make[1]: *** [crypto/comp/c_zlib.o] Error 1
make[1]: Leaving directory `/home/softback/openssl-1.1.1d'
make: *** [all] Error 2
查找相关资料和文档,有一条说到是可以尝试不使用压缩模块来进行配置和编译。
Ok,满怀信心的开始第二次尝试,取消模块压缩。
第三次错误:
> ./config shared
----- 这里顺利 -----
> make
……
----- 就是等待的时间比不压缩久了大概 2~3分钟 ----
……
apps/libapps.a -lssl -lcrypto -ldl -pthread
./libcrypto.so: undefined reference to 'BI0_f_zlib'
collect2: error: Id returned 1 exit status
make [1]:*** [apps/openssl] Error 1
make [1]:Leaving directory '/home/openssl-1.1.Id'
make: *** [all] Error 2
说好的可以不压缩呢?Are you kidding me?行吧,继续查相关资料和文档把。
在文档中又看到可以只指定压缩其中的一个模块。
Fine!!!继续开始尝试。
第三次错误:
> ./config shared zlib --prefix=/home/openssl-1.1.1d/apps/openssl
----- 这里顺利 -----
> make
……
……
……
/usr/bin/ld: cannot find -lz
collect2: error: Id returned 1 exit status
make[1]: *** [libcrypto.so] Error 1
make[1]:Leaving directory '/home/openssl-1.1.1d
make: *** [all] Error 2
我的天!这它喵的都是什么文档,到底还有没有谱的啊!
不行,这不可能就我一个人错,中文搜索不行,我还不能用英文么?
但然而结果就是,还是在搜到了最终解决的结果,万万想不到居然是中文的。
apt-cache search zlib
Ubuntu 下 zlib 的包并不叫 zlib!!!
zlib -> zlib1g
zlib-dev -> zlib1g-dev
行吧!既然如此,在检查系统里安装 zlib 的情况后发现缺少了 zlib-dev。
apt-get install zlib1g-dev
安装完成后继续尝试:
> ./config shared zlib
----- 这里顺利 -----
> make
……
----- 大概2分钟左右 -----
……
----- 顺利 -----
> make install
----- 顺利完成安装 -----
反正到这里虽然已经顺利完成安装了,但我的内心是崩溃的。
虽然到了这里,你以为就结束了?
天真,远远并没有结束!
当你想尝试查看 OpenSSL 是否正确安装的时候:
> openssl version -a
/usr/local/openssl/bin/openssl: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory.
恭喜你又踩到另外一个坑。
不过没关系,这个并不是什么奇怪的错误,只是库的链接位置不对,找不到文件而已。
所以在这里让你不要害怕以及很不负责的强迫你按照以下命令一条一条的执行,如果报错也可以不用管。
为什么?!没有为什么,只是原路径没有这个文件而已,忽略即可。
> mv /usr/bin/openssl /usr/bin/openssl.old
> mv /usr/include/openssl /usr/include/openssl.old
> ln -s /usr/local/bin/openssl /usr/bin/openssl
> ln -s /usr/local/include/openssl/ /usr/include/openssl
> ln -s /usr/local/lib/libssl.so.1.1 /usr/lib/libssl.so.1.1
> ln -s /usr/local/lib/libcrypto.so.1.1 /usr/lib/libcrypto.so.1.1
其实呢,这里都是将 OpenSSL 的文件以及库文件进行了软链接到另外一个文件路径下而已,然后系统就可以通过这个软链接正确的找到相关的文件了。
至此,关于 OpenSSL 部分的编译就完成了。
还记得文章开头我让你保存的 Nginx 的 configure argument 配置信息吧?
Ok,没错现在就是到了要使用的时候了。
首先要确认你的 Nginx 版本是多少,然后就需要从官网上下载一毛一样的版本了。不要问为什么,照做就对了。
官方下载源:https://nginx.org/en/download.html
这里我以 1.14.0 版本为例:
wget http://nginx.org/download/nginx-1.14.0.tar.gz
下载完成后解压该文件
tar -zxvf nginx-1.14.0.tar.gz
进入解压后的文件夹
cd nginx-1.14.0
使用 configure 来对 Nginx 进行安装配置,这里将如下信息与你之前保存的 Nginx 配置信息进行对比,看看到底缺哪个。
并且不要着急回车执行命令。
./configure --prefix=/你的文件夹路径 --with-http_v2_module --with-openssl=OpenSSL解压包的路径
请千万确保处理好配置信息之前,不要贸然复制到命令行执行,不然 Nginx 无法工作了不要怪我!!!
配置完成后接下来就可以尝试编译了
make
这里不用 make install !!!
这里不用 make install !!!
这里不用 make install !!!
千万不要手贱!!!
坐等编译完成,然后执行如下命令:
> nginx stop
> cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.back
首先停止 Nginx 服务,然后在复制一份旧版作为备份。
然后再将你指定编译文件内的 nginx 复制过来替换。
这也就是我为什么要让你找同版本的 Nginx 的原因,这样就不会因为版本不对导致的其他问题。
替换完成后执行:
nginx -s restart
至此,如果你能像我一样没有发生其他错误,那么就恭喜你,你已经完成了 Nginx 的 HTTP 2.0 升级了。(什么?报错了?那你还不赶快去查资料?)
阿里云/腾讯云都有免费的CA证书服务。我这有阿里云的优惠券和腾讯云服务器的优惠券,留言我发你。
现在的云服务器提供商都有相关的配套服务了,所以不用担心太多问题。申请证书之后按照步骤操作,最后下载证书放到服务器上就好了。
server {
listen 443 ssl http2; # 添加 http 2.0 服务标识
# 你的 CA 证书路径
ssl_certificate /xxx/3076402_123456.com.pem;
ssl_certificate_key /xxx/3076402_123456.com.key;
……
……
……
}
配置完成保存后就可以执行重新加载 nginx 配置的命令了。
nginx -s reload
事实很残酷!并没有像预想中一样一次完成,又整了一出幺蛾子给我。
404 Not Found | http/1.1
为什么找不到资源,为什么还是 http 1.1?!!
但是这次我决定先解决 404 的问题,既然是访问错误那么就可以从日志中入手,查看了 nginx-error.log 文件发现:
open() "/www/error/443" failed (2: No such file or directory)
为什么会找不到文件路径?我仔细一看,这个路径为什么会是 /www/error + /443,难道我的配置路径错了?这也不应该啊,在没升级之前,都是可以正确访问的吖。
行吧,还是面向百度编程一下吧!然后发现是配置规则也更新了。
修改将目录路径闭合
location / {
alias /www/error/; # root /www/error; 旧配置未闭合目录路径
index 404.html;
}
修改完信息后执行重新加载 nginx 配置的命令
nginx -s reload
之后再刷新页面就可以看到正确的页面以及显示出 HTTP 2.0 版本的标识 h2 了。
Congratulations!!!
你已经完成了 Nginx HTTP 2.0 的升级了。
敢问少侠可知道七伤拳?
阿里云ECS升级OpenSSL记录 - 杜先生的博客:(有用) https://www.cnblogs.com/dukuan/p/7833478.html 阿里云帮助文档:(至少一半无用信息) https://help.aliyun.com/knowledge_detail/52154.html 相似错误:(但并没解决我的问题) https://blog.csdn.net/java3344520/article/details/8612367 关于子目录路径: https://segmentfault.com/q/1010000006194225/a-1020000006195489
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。