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 前面不能加空格。
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
流程如下:
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; # 实时性高
经过上述内容的优化,我们再次思考一个问题,假如在满足上述优化的前提下,我们传送一个 1M 的数据和一个 10M 的数据那个效率高?答案显而易见,传输内容小,速度就会快。那么问题又来了,同样的内容,如果把大小降下来,我们脑袋里面要蹦出一个词就是「压缩」,接下来,我们来学习 Nginx 的静态资源压缩模块。
在 Nginx 的配置文件中可以通过配置 gzip 来对静态资源进行压缩,相关的指令可以配置在 http 块、server 块和 location 块中,Nginx 可以通过对这些指令进行解析和处理:
接下来我们从以下内容进行学习:
接下来所学习的指令都来自 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资源。
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; # 缓存空间大小
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 |
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
前面在讲解 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 -V # 拷贝 configure arguments 后面的数据
cd /usr/local/nginx/sbin mv nginx nginx.backup
cd /root/nginx-1.22.0
make clean
./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
mv objs/nginx /usr/local/nginx/sbin
cd /root/nginx-1.22.0 make upgrade
准备好一个 jquery.js 文件,放在 html 目录下
# 进入 html 目录 cd /usr/local/nginx/html # 压缩 js 文件 gzip jquery.js