error_page指令
error_page 指令是设置网站的错误页面。
语法 | 默认值 | 位置 |
---|---|---|
error_page ...... [=[response]] |
— | http、server、location ...... |
code是响应码。
当出现对应的响应code后,如何来处理?
- 可以指定具体的跳转的地址
server {
error_page 404 https://www.baidu.com;
}
当页面产生 404 时,自动跳转到 http://www.frx.com
2. 可以指定重定向地址
server {
error_page 404 /404.html;
location =/404.html {
root html;
}
}
产生错误页面时,重定向到 /50x.html,然后触发 location,最终访问的是 html 目录下的 50x.html 页面
3. 使用location的@符号完成错误信息展示
server {
error_page 404 @jump_to_error;
location @jump_to_error {
return 404 'not found error';
}
}
可选项 =[response] 的作用是用来将相应代码更改为另外一个,如下:
server {
error_page 404 =200 /404.html;
location =/404.html {
root html;
}
}
这样的话,当返回 404 找不到对应的资源的时候,在浏览器上可以看到,最终返回的状态码是 200 而不是 404,这块需要注意下,编写 error_page 后面的内容,404 后面需要加空格,200 前面不能加空格。
静态资源优化配置之sendfile
Nginx 对静态资源如何进行优化配置。这里从三个属性配置进行优化:
sendfile on;
tcp_nopush on;
tcp_nodeplay on;
建议三个都开启。如果想知道为什么,请往下看。
sendfile
该指令是用来开启高效的文件传输模式。默认关闭,建议开启。
语法 | 默认值 | 位置 |
---|---|---|
sendfile <on | off>; | sendfile off; |
请求静态资源的过程:客户端通过网络接口向服务端发送请求,操作系统将这些客户端的请求传递给服务器端应用程序,服务器端应用程序会处理这些请求,请求处理完成以后,操作系统还需要将处理得到的结果通过网络适配器传递回去。
如:
server {
listen 80;
server_name mayanan.cn;
location / {
root html;
index index.html;
}
}
假设在 html 目录下有一个 welcome.html 页面,访问地址:http://mayanan.cn/welcome.html
流程如下:
nginx静态资源优化配置之tcp_nopush和tcp_nodeplay
tcp_nopush
该指令必须在 sendfile 打开的状态下才会生效,主要是用来提升网络包的传输「效率」。默认关闭。
语法 | 默认值 | 位置 |
---|---|---|
tcp_nopush <on | off>; | tcp_nopush off; |
tcp_nodeplay
该指令必须在 keep-alive 连接开启的情况下才生效,来提高网络包传输的「实时性」。默认开启。
语法 | 默认值 | 位置 |
---|---|---|
tcp_nodelay <on | off>; | tcp_nodelay on; |
tcp_nopush 就像大巴车,等所有旅客占满了座位,才开始发车到景点(客户端),而 tcp_nodelay,上来一个旅客,就马上发车到景点客户端)。
优化总结
经过分析,『 tcp_nopush 』和『 tcp_nodelay 』看起来是「互斥的」,那么为什么要将这两个值都打开,这个大家需要知道的是在 Linux2.5.9 以后的版本中两者是可以兼容的,三个指令都开启的好处是,sendfile 可以开启高效的文件传输模式,『 tcp_nopush 』开启可以确保在发送到客户端之前数据包已经充分「填满」,这大大减少了网络开销,并加快了文件发送的速度。然后,当它到达最后一个可能因为没有「填满」而暂停的数据包时,Nginx 会忽略『 tcp_nopush 』参数, 然后,『 tcp_nodelay 』强制套接字发送数据。由此可知,『 tcp_nopush 』可以与『 tcp_nodelay 』一起设置,它比单独配置『 tcp_nodelay 』具有更强的性能。
所以回归开头,我们可以使用如下配置来优化 Nginx 静态资源的处理:
sendfile on; # 配置允许使用 sendfile 方式高效传输文件
# tcp_nopush+tcp_nodeplay都开启,性能最强
tcp_nopush on; # 传输效率高
tcp_nodelay on; # 实时性高
nginx静态资源压缩实战
经过上述内容的优化,我们再次思考一个问题,假如在满足上述优化的前提下,我们传送一个 1M 的数据和一个 10M 的数据那个效率高?答案显而易见,传输内容小,速度就会快。那么问题又来了,同样的内容,如果把大小降下来,我们脑袋里面要蹦出一个词就是「压缩」,接下来,我们来学习 Nginx 的静态资源压缩模块。
在 Nginx 的配置文件中可以通过配置 gzip 来对静态资源进行压缩,相关的指令可以配置在 http 块、server 块和 location 块中,Nginx 可以通过对这些指令进行解析和处理:
- ngx_http_gzip_module 模块
- ngx_http_gzip_static_module 模块
- ngx_http_gunzip_module 模块
接下来我们从以下内容进行学习:
- Gzip 各模块支持的配置指令
- Gzip 压缩功能的配置
- Gzip 和 sendfile 的冲突解决
- 浏览器不支持 Gzip 的解决方案
nginx的Gzip模块配置指令1
接下来所学习的指令都来自 ngx_http_gzip_module 模块,该模块会在 Nginx 安装的时候内置到 Nginx 的安装环境中,也就是说我们可以直接使用这些指令。
Gzip
指令是用于开启或者关闭 Gzip 功能。默认关闭
语法 | 默认值 | 位置 |
---|---|---|
gzip <on | off>; | gzip off; |
注意:只有该指令为打开状态,下面的指令才有效果
http {
gzip on;
}
gzip_types
指令可以根据响应页的 MIME 类型选择性地开启 Gzip 压缩功能。默认是 text/html
语法 | 默认值 | 位置 |
---|---|---|
gzip_types |
gzip_types text/html; | http、server、location |
所选择的值可以从 mime.types 文件中进行查找,也可以使用 * 代表所有。
http{
gzip_types application/javascript;
# * 代表所有
gzip_types *
}
注意:实际生产环境中不建议将gzip_types设置为*,因为像一些图片、视频等资源已经进行了高度压缩,如果在进行压缩效果不明显,而且还会浪费CPU资源。
nginx的gzip模块配置指令2
gzip_comp_level 指令是用于设置 Gzip 压缩程度,级别从 1-9,1 表示要是程度最低,要是效率最高,9 刚好相反,压缩程度最高,但是效率最低、最费时间。默认值是 1
语法 | 默认值 | 位置 |
---|---|---|
gzip_comp_level |
gzip_comp_level 1; | http、server、location |
gzip_vary
指令是用于设置使用 Gzip 进行压缩发送是否携带『Vary:Accept-Encoding』头域的响应头部。主要是告诉接收方,所发送的数据经过了 Gzip 压缩处理。默认关闭
语法 | 默认值 | 位置 |
---|---|---|
gzip_vary <on | off>; | gzip_vary off; |
gzip_buffers
指令是用于处理请求压缩的缓冲区数量和大小
语法 | 默认值 | 位置 |
---|---|---|
gzip_buffers |
gzip_buffers 32 4k | 16 8k; |
其中 number 是指定 Nginx 服务器向系统申请缓存空间个数,size 指的是每个缓存空间的大小。主要实现的是申请 number 个每个大小为 size 的内存空间。这个值的设定一般会和服务器的操作系统有关,所以建议此项不设置,使用默认值即可。
gzip_buffers 4 16K; # 缓存空间大小
nginx的gzip模块配置指令3
gzip_disable
指令是针对不同种类客户端发起的请求,可以选择性地开启和关闭 Gzip 功能
语法 | 默认值 | 位置 |
---|---|---|
gzip_disable |
— | http、server、location |
regex 是根据客户端的浏览器标志(user-agent)来设置,支持使用正则表达式。指定的浏览器标志不使用 Gzip.该指令一般是用来排除一些明显不支持 Gzip 的浏览器。
gzip_disable 'Mozilla\/5\.0.*';
比如说禁用ie6一下版本的gzip压缩都禁用掉:
gzip_disable "MSIE [1-6]\.";
gzip_http_version
指令是针对不同的 HTTP 协议版本,可以选择性地开启和关闭 Gzip 功能。默认是 1.1 版本
语法 | 默认值 | 位置 |
---|---|---|
gzip_http_version <1.0 | 1.1>; | gzip_http_version 1.1; |
该指令是指定使用 Gzip 的 HTTP 最低版本,该指令一般采用默认值即可。
gzip_min_length
指令是针对传输数据的大小,可以选择性地开启和关闭 Gzip 功能
语法 | 默认值 | 位置 |
---|---|---|
gzip_min_length |
gzip_min_length 20; | http、server、location |
Nignx 计量大小的单位:bytes [字节] / kb [千字节] / M [兆]
例如: 1024 / 10k | K / 10m | M
Gzip 压缩功能对大数据的压缩效果明显,但是如果要压缩的数据比较小的话,可能出现越压缩数据量越大的情况,因此我们需要根据响应内容的大小来决定是否使用 Gzip 功能,响应页面的大小可以通过头信息中的 Content-Length 来获取。但是如何使用了 Chunk 编码动态压缩,该指令将被忽略。建议设置为 1K 或以上。
gzip_proxied
指令设置是否对服务端返回的结果进行 Gzip 压缩
语法 | 默认值 | 位置 |
---|---|---|
gzip_proxied <off | expired | no-cache |
- off:关闭 Nginx 服务器对后台服务器返回结果的 Gzip 压缩
- expired:如果 header 头中包含 『Expires』头信息,启用压缩
- no-cache:如果 header 头中包含 『Cache-Control:no-cache』头信息,启用压缩
- no-store:如果 header 头中包含 『Cache-Control:no-store』头信息,启用压缩
- private:如果 header 头中包含 『Cache-Control:private』头信息,启用压缩
- no_last_modified:如果 header 头中不包含 『Last-Modified』头信息,启用压缩
- no_etag:如果 header 头中不包含 『ETag』 头信息,启用压缩
- auth:如果 header 头中包含 『Authorization』 头信息,启用压缩
- any:无条件启用压缩
nginx中gzip压缩功能的实例配置
gzip on; # 开启 Gzip 功能
gzip_types *; # 压缩源文件类型,根据具体的访问资源类型设定
gzip_comp_level 6; # Gzip 压缩级别
gzip_min_length 1k; # 进行压缩响应页面的最小长度,content-length
gzip_buffers 4 16K; # 缓存空间大小
gzip_http_version 1.1; # 指定压缩响应所需要的最低 HTTP 请求版本
gzip_vary on; # 往头信息中添加压缩标识
gzip_disable "MSIE [1-6]\."; # 对 IE6 以下的版本都不进行压缩
gzip_proxied off; # Nginx 作为反向代理压缩服务端返回数据的条件
这些配置在很多地方可能都会用到,所以我们可以将这些内容抽取到一个配置文件中,然后通过 include 指令把配置文件再次加载到 nginx.conf 配置文件中,方法使用。
创建压缩配置文件:nginx_gzip.conf,添加如下内容:
gzip on;
gzip_types *;
gzip_comp_level 6;
gzip_min_length 1k;
gzip_buffers 4 16K;
gzip_http_version 1.1;
gzip_vary on;
gzip_disable "MSIE [1-6]\.";
gzip_proxied off;
在 Nginx 核心配置文件 nginx.conf 进行引入,添加如下内容:
include nginx_gzip.conf
gzip和sendfile共存问题
前面在讲解 sendfile 的时候,提到过,开启 sendfile 以后,在读取磁盘上的静态资源文件的时候,可以减少拷贝的次数,可以不经过用户进程将静态文件通过网络设备发送出去,但是 Gzip 要想对资源压缩,是需要经过用户进程进行操作的。所以如何解决两个设置的共存问题。
可以使用 ngx_http_gzip_static_module 模块的 gzip_static 指令来解决。
gzip_static指令
gzip_static
指令用于在检查与访问资源同名的 .gz 文件时,response 中以 Gzip 相关的 header 返回 .gz 文件的内容。默认关闭。
语法 | 默认值 | 位置 |
---|---|---|
gzip_static <on | off | always>; |
gzip_static on;
在配置文件添加上述命令后,会报一个错误:unknown directive "gzip_static",主要的原因是 Nginx 默认是没有添加 ngx_http_gzip_static_module 模块。如何来添加?
nginx中添加gzip_static支持
nginx模块添加
- 查询当前 Nginx 的配置参数,即查看 configure arguments 的配置信息,拷贝出来
nginx -V
# 拷贝 configure arguments 后面的数据
- 将 Nginx 安装目录下 sbin 目录中的 nginx 二进制文件进行更名备份
cd /usr/local/nginx/sbin
mv nginx nginx.backup
- 进入nginx的安装目录
cd /root/nginx-1.22.0
- 执行 make clean 清空之前编译的内容
make clean
- 使用 configure 来配置参数,添加 ngx_http_gzip_static_module 模块,记得加上第1步拷贝的配置信息
./configure --prefix=/usr/local/nginx --sbin-path=/usr/local/nginx/sbin/nginx --modules-path=/usr/local/nginx/modules --conf-path=/usr/local/nginx/conf/nginx.conf --error-log-path=/usr/local/nginx/logs/error.log --http-log-path=/usr/local/nginx/logs/access.log --pid-path=/usr/local/nginx/logs/nginx.pid --lock-path=/usr/local/nginx/logs/nginx.lock --with-http_gzip_static_module
- 使用make命令进行编译
make
- 将 objs 目录下的 nginx 二进制执行文件移动到 nginx 安装目录下的 sbin 目录中
mv objs/nginx /usr/local/nginx/sbin
如果不执行第(2)步进行备份,则该步骤会覆盖原来的 nginx 可执行文件 - 在源码目录下执行更新命令
cd /root/nginx-1.22.0
make upgrade
nginx中gzip_static使用测试
准备好一个 jquery.js 文件,放在 html 目录下
- 直接访问http://mayanan.cn/jquery.js
Content-Length: 289812 - 使用gzip命令进行压缩
# 进入 html 目录
cd /usr/local/nginx/html
# 压缩 js 文件
gzip jquery.js
- 再次访问:http://mayanan.cn/jquery.js
Content-Length: 85347
可以看出 Content-Length 的大小已经变得非常小。