古老的榕树

配置编译 Nginx 让网站用上 HTTP2

潘军杰 发表于 2018-02-07 23:34 阅读(3020) 评论(0) 赞(2)
HTTP2 出来有一阵子了,一直想把公司的项目用上 HTTP2,了解了一下技术要求。首先 HTTP2 似乎需要到 SSL 证书,腾讯云和阿里云都有免费试用一年的 SSL 证书,腾讯云的证书用满一年后,还可以重新免费申请续用,至少目前还是这样的。

使用 HTTP2 只要搞定 Web 服务器,比如 Apached 和 Nginx,其他的后端程序不用做任何改动。当然前提是使用 Web 服务器代理后端程序,如果项目避开 Web 服务器,直接采用 Tomcat,Jboss Jetty,Undertow 这些容器来提供服务,不是本次讨论的范畴。

本人的环境是 Debian + Nginx 1.6.2,因为 Nginx 1.9.5 或以上才真正支持 HTTP2,当时在 Debian 上通过 apt-get install nginx 命令来安装,显然 Nginx 版本比较老,需要把 Nginx 升级到最新的版本,才符合要求,这就是本次主要讨论的东西了。


先查询 Nginx 现有的配置情况和安装的路径:
>>> nginx -V

```
configure arguments: --with-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' --with-ld-opt=-Wl,-z,relro --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_spdy_module --with-http_sub_module --with-http_xslt_module --with-mail --with-mail_ssl_module --add-module=/build/nginx-1.6.2/debian/modules/nginx-auth-pam --add-module=/build/nginx-1.6.2/debian/modules/nginx-dav-ext-module --add-module=/build/nginx-1.6.2/debian/modules/nginx-echo --add-module=/build/nginx-1.6.2/debian/modules/nginx-upstream-fair --add-module=/build/nginx-1.6.2/debian/modules/ngx_http_substitutions_filter_module 
```

>>> whereis nginx

```
/usr/sbin/nginx /etc/nginx /usr/share/nginx /usr/share/man/man1/nginx.1.gz
```

注意以上两点很重要,我们升级到最新的 Nginx 时会用到。


开始动工了,我们先下载最新的 nginx,openssl,zlib,因为 debian 比较保守,这三个包都比较老,需要更换为比较新的版本,才能支持 HTTP2,本人就是之前就是因为忽略了 openssl,zlib 的版本,升级了 nginx 后,才发现徒劳没成功,走了一些弯路。

openssl,zlib的官网如下:
https://www.openssl.org/source/
http://zlib.net/

我们先把 openssl,zlib 下载到指定的目录下:
/usr/local/

>>> cd /usr/local/
>>> wget https://www.openssl.org/source/openssl-1.0.2n.tar.gz
>>> wget http://prdownloads.sourceforge.net/libpng/zlib-1.2.11.tar.gz

然后就在当前目录细解压缩:
>>> tar -zxvf openssl-1.0.2n.tar.gz
>>> tar -zxvf zlib-1.2.11.tar.gz

原料已经准备好了,我们开始到 nginx 官网下载最新的版本了,地址:
http://nginx.org/en/download.html

我们把最新的 nginx 1.12.2 下载到一个好记的路径下,后面我们配置和编译的时候,方便操作,就 /home 下吧
>>> cd /home
>>> wget http://nginx.org/download/nginx-1.12.2.tar.gz

解压缩 nginx:
>>> tar -zxvf nginx-1.12.2.tar.gz


配置和编译最新版的 nginx 之前,需要说明一下重要的几个步骤,这个关系都编译能否成功的,首先,需要安装一些必要的模块,然后把 nginx 老配置稍微做一下调整。
安装一些必要的模块:
>>> apt-get update
>>> apt-get install libpcre3 libpcre3-dev
>>> apt-get install libxml2 libxslt-dev
>>> apt-get install libgd2-xpm-dev
>>> apt-get install libgeoip-dev

首先是 update 一下系统源,然后安装以上四个小模块(安装了它们之后,一般都可以编译 nginx 了),这些步骤很费神,系统依赖环境不同,可能遇到的问题也不一样,总之编译 nginx 的时候,提示缺少什么模块,百度一下吧,就安装什么即可,这里省了未知的问题了。

另外我们把 nginx 老的配置参数做一些删减,去掉没有用的,比如 spdy 模块,1.6.2 的老模块:
--with-http_spdy_module --add-module=/build/nginx-1.6.2/debian/modules/nginx-auth-pam --add-module=/build/nginx-1.6.2/debian/modules/nginx-dav-ext-module --add-module=/build/nginx-1.6.2/debian/modules/nginx-echo --add-module=/build/nginx-1.6.2/debian/modules/nginx-upstream-fair --add-module=/build/nginx-1.6.2/debian/modules/ngx_http_substitutions_filter_module 

增加 HTTP2 必须的,其中就有我们刚下载的 openssl 和 zlib
--with-openssl=/usr/local/openssl-1.0.2n --with-pcre --with-zlib=/usr/local/zlib-1.2.11 --with-stream --with-stream_ssl_module --with-http_v2_module --with-threads

增删做好后,最终配置参数如下:
```
--with-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' --with-ld-opt=-Wl,-z,relro --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_sub_module --with-http_xslt_module --with-mail --with-mail_ssl_module  --with-openssl=/usr/local/openssl-1.0.2n --with-pcre --with-zlib=/usr/local/zlib-1.2.11 --with-stream --with-stream_ssl_module --with-http_v2_module --with-threads
```

工作都就绪了,我们开始配置和编译最新版的 nginx 了:
>>> cd nginx-1.12.2
>>> ./configure --with-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' --with-ld-opt=-Wl,-z,relro --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_sub_module --with-http_xslt_module --with-mail --with-mail_ssl_module  --with-openssl=/usr/local/openssl-1.0.2n --with-pcre --with-zlib=/usr/local/zlib-1.2.11 --with-stream --with-stream_ssl_module --with-http_v2_module --with-threads

以上步骤是配置 nginx,过程需要点时间,如果不幸提示缺少什么模块,就安装什么,不过上面工作都做好了,一般都会通过的。

编译 nginx,注意:只需要编译 make,不需要安装 make install。
>>> make

以上步骤是编译,需要较长的时间,耐心等待编译完成后,会发现 /home/nginx-1.12.2/objs 目录下多个了一个 nginx 可执行文件,这就是我们要编译出来的东西了,然后替换掉老 nginx,重启新 nginx 。

以防新编译出来的 nginx 出错,我们把老的 nginx 备份一下:
>>> mv /usr/sbin/nginx /usr/sbin/nginx.20180207.bak

新 nginx 替换掉老 nginx
>>> cp -rf objs/nginx /usr/sbin/nginx

测试现有的网站配置,自动检查网站配置是否有误。
>>> /usr/sbin/nginx -t

如果测试成功,就可以直接把老 nginx 进程杀死,启动新 nginx 进程了,注意老 nginx 的 pid 在上面的 nginx 配置文件里就包含有,要根据具体的 pid 路径,杀死它。
>>> kill -USR2 `cat /run/nginx.pid`
>>> kill -QUIT `cat /run/nginx.pid.oldbin`

重启新 nginx 
service nginx restart

查看升级是否生效?
>>> /usr/sbin/nginx -V

如果生效的话你会看到
```
nginx version: nginx/1.12.2
built by gcc 4.9.2 (Debian 4.9.2-10) 
built with OpenSSL 1.0.2n  7 Dec 2017
TLS SNI support enabled
```

最后 nginx 已经完全升级成功了,我们把自己的网站应用配置改成 HTTP2 方式,比如网站应用配置路径在:
/etc/nginx/sites-enable/my_project.conf

打开配置文件:

>>>nano /etc/nginx/sites-enable/my_project.conf

直接把 listen 值改成为 HTTP2 的模式即可,就一个地方的改动。比如:

listen 443 ssl;
改成
listen 443 ssl http2;

最后重启 nginx
>>> service nginx restart

验证 HTTP2 是否生效,在 chrome 浏览器上,打开你的应用域名,比如 your-domain.com,然后再用另外的标签,打开这个地址:
chrome://net-internals/#http2

如果生效的话,你会看到 HTTP/2 sessions 列表里有此域名。
your-domain.com:443 128740 h2
标签: nginx http2 ssl
0 条网友评论

哇~~~ 竟然还没有评论!

称呼*
邮箱*
内容*
验证码*
验证码 看不清换张