135.Nginx(四):nginx配置成系统服务,静态资源相关指令,压缩功能,静态资源缓存,跨域,防盗链

目录

一、nginx服务操作的问题

二、nginx配置成系统服务

三、nginx命令配置到系统环境

四、nginx静态资源部署指令

1.listen指令

2.server_name

(1)server_name:用来设置虚拟主机服务名称

(2)server_name的三种配置方式

(3)常见的正则表达式 

(4)server_name匹配优先级顺序

3.location指令

4.设置请求资源的目录root/alias

(1)root指令

(2)alias指令

(3)区别

5.index指令

6.error_page指令

(1)error_page:设置网站的错误页面

(2)uri的三种形式

(3)可选项=response

五、静态资源优化配置语法

1.sendfile指令

 2.tcp_nopush指令

3.tcp_nodelay指令

4.三个指令要一起使用

六、nginx静态资源压缩:Gzip模块指令

七、ngx_http_gzip_module模块指令

1.gzip指令

2.gzip_types指令

3.gzip_comp_level指令

4.gzip_vary指令

5.gzip_buffers指令

6.gzip_disable指令

7.gzip_http_version指令

8.gzip_min_length指令

9.gzip_proxied指令

八、gzip压缩功能的实例配置

九、ngx_http_gzip_static_module模块指令:解决Gzip和sendfile共存问题

1.问题

2.解决思路

3.gzip_static指令

4.导入ngx_http_gzip_static_module模块

5.测试

十、 静态资源的缓存处理

1.浏览器缓存的执行过程

2.浏览器缓存相关指令

(1)expires指令

(2)add_header指令

十一、nginx的跨域问题

1.同源策略

2.跨域问题

3.解决方案

十二、静态资源防盗链

1.什么是资源盗链

2.防盗链的实现原理

3.具体实现:valid_referers指令

十三、打赏请求


一、nginx服务操作的问题

如果想要启动、关闭或者重新加载nginx配置文件,都需要先进入到nginx的安装目录的sbin目录,然后使用nginx的二进制可执行文件来操作,这很麻烦。

我们想把nginx设置成随着服务器启动就自动完成启动,这个如何实现:

(1)nginx配置成系统服务

(2)nginx命令配置到系统环境

二、nginx配置成系统服务

把nginx应用服务设置成系统服务,方便nginx服务的启动和停止等相关操作。

#添加一个nginx.service文件
vim /usr/lib/systemd/system/nginx.service

###########################################################
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s stop
PrivateTmp=true

[Install]
WantedBy=default.target

###########################################################

#配置权限
chmod 755 /usr/lib/systemd/system/nginx.service

#使用系统命令来操作nginx服务
#启动
systemctl start nginx

#停止
systemctl stop nginx

#重启
systemctl restart nginx

#重新加载配置文件
systemctl reload nginx

#查看nginx状态
systemctl status nginx

#开机启动
systemctl enable nginx

注:如果你的系统命令不起作用,重启一下虚拟机

三、nginx命令配置到系统环境

vim /etc/profile

#按G调到最后一行
##############################################
export PATH=$PATH:/usr/local/nginx/sbin
##############################################

source /etc/profile
nginx -v


四、nginx静态资源部署指令

静态资源:对于一些html、css、js、图片、视频等静态资源,服务器真实存在,直接拿出来展示

动态资源:需要经过逻辑判断动态获取、权限过滤后的信息

1.listen指令

 listen:用来配置监听端口

#语法
listen address[:port] [default server];
listen port [default server];

#默认值
listen *:80 |*:8000

#位置
server

listen的设置比较灵活,我们通过几个例子把常用的设置属性下:

listen 127.0.0.1:8000;
listen localhost:8000;
listen 127.0.0.1;
listen 8000;
listen *:8000;

default_server属性是标识符,用来将此虚拟主机设置成默认主机。所谓的默认主机指的是如果没有匹配到对应的address:port,则会默认执行。如果不指定,默认使用第一个server

listen 80 default_server;

2.server_name

(1)server_name:用来设置虚拟主机服务名称

#语法
server_name name...;

#默认值
server_name "";

#位置
server

(2)server_name的三种配置方式

  • 精确匹配:在hosts里做匹配
  • 通配符匹配:*代表任意字符,但是只能出现在开头或者结尾
  • 正则表达式匹配:需要使用~作为正则表达式开始标记

hosts类似于一个映射表,把ip和域名映射起来,我们测试的时候就这样用:

#windows系统hosts位置:
C:\Windows\System32\drivers\etc\hosts

#linux系统hosts位置:
/etc/hosts

在hosts设置域名

 在虚拟机测试,如果在本机测试不行,因为没有在本机设置ip和域名的对应:

(3)常见的正则表达式 

^ 匹配搜索字符串开始位置
$ 匹配搜索字符串结束位置
. 匹配出换行符\n之外的任何单个字符
\ 转义字符,讲下一个字符标记为特殊字符
[xyz] 字符集,与任意一个指定字符匹配
[a-z] 字符范围,匹配指定范围内的任何字符
\w 与一下任意字符匹配A-Z a-z 0-9和下划线,等效于[A-Za-z0-9]
\d 数字匹配,等效于[0-9]
{n} 正好匹配n次
{n,} 至少匹配n次
{n,m} 至少n次,最多m次
* 0次或多次,等效于{0,}
+ 一次或多次,等效于{1,}
? 0次或一次,等效于{0,1}

(4)server_name匹配优先级顺序

  1. 精确匹配
  2. 通配符在开始匹配
  3. 通配符在结束
  4. 正则表达式匹配
  5. 被默认的default_server处理,如果没有再默认找第一个server

3.location指令

location:用来设置请求的uri

#语法
location [=|~|~*|^~|@] uri{...};

#位置
server ,location
  • 不带符号:/abc。那么/abdcd也可以,只要abc开头即可。如果这个匹配了还会继续往后找,后面如果还有匹配会先用后面。
  • =:=/abc。只有/abc可以,/abcd不可以。但是/abc?aa=1可以,因为?可以理解为参数
  • ~:~正则表达式。表明uri中有正则表达式,并且区分大小写
  • ~*:~*正则表达式。表明uri中有正则表达式,并且不区分大小写
  • ^~:用于不包含正则表达式uri前面。如果这个模式匹配了,就不找后面的了,直接用这个

4.设置请求资源的目录root/alias

(1)root指令

root:设置请求资源的根目录

#语法:此处path为nginx服务器接收到请求以后查找资源的根目录
root path;

#默认值
root html;

#位置
http、server、location

(2)alias指令

alias:用来更改location的uri

#语法:此处path为修改后的根路径
alias path;

#位置
location

(3)区别

root指令对应路径 = root路径 + location路径

alias指令对应路径 = root路径 + alias路径

注1:比如,当前一张图片路径为:/usr/local/nginx/html/image/mv.jpg

location为/image

root指令对应path为:html(因为root会默认吧location对应的image加到后面)

alias指令对应path为:html/image

注2:如果location为/image/,那么alias也需要改为html/image/,而boot不会有影响

5.index指令

index:设置网站的默认首页

#语法
index file...;

#默认值
index index.html;

#位置
http,server,location

index后面可以跟多个设置,如果访问的时候没有制定具体访问的资源,则会依次进行查找,直到找到一个为止

6.error_page指令

(1)error_page:设置网站的错误页面

#语法
error_page code... [=[response]] uri;

#位置
http,server,location

(2)uri的三种形式

  • 直接跟地址
  • 指定重定向地址:/uri,然后location =/url{}
  • @完成错误信息展示:@名称。然后location @名称{}

(3)可选项=response

error_page 404 =200 /50x.html;

就是说,如果404找不到,最后返回给浏览器的状态码不是404而是200,但是页面还是404本该有的页面

五、静态资源优化配置语法

nginx对静态资源如何进行优化配置,主要是三个指令:

  • sendfile on;
  • tcp_nopush on;
  • tcp_nodelay on;

1.sendfile指令

sendfile:用来开启高效的文件传输模式

#语法
sendfile on|off;

#默认
sendfile off;

#位置
http,server,location

如果没使用sendfile,我们传输一次静态自己需要拷贝4次,还涉及到了内核的切换(用户区与内核区切换):

 使用了sendfile后,只拷贝两次,还省去了内核区和用户区的切换:

 2.tcp_nopush指令

tcp_nopush:该指令必须在sendfile打开的状态下才生效,主要是用来提升网络包的传输效率

#语法
tcp_nopush on|off;

#默认
tcp_nopush off;

#位置
http,server,location

3.tcp_nodelay指令

tcp_nodelay:该指令必须在keep_alive连接开启的情况下才生效,来提高网络包传输的实时性

#语法
tcp_nodelay on|off;

#默认
tcp_nodelay on;

#位置
http,server,location

4.三个指令要一起使用

注1:

  • tcp_nopush注重效率,数据填满缓冲区一次性发送。
  • tcp_nodelay注重实时性,一有数据就发送

注2:

tcp_nopush和tcp_nodelay看起来互斥,但是在linux2.5.9之后可以兼容,这三个指令建议都打开,好处是:

  • sendfile可以开启高效文件传输模式
  • tcp_nopush可以确保在发送到客户端之前数据包已经填满,减少网络开销,加快文件传送速度。当最后一个包数据没有填满的时候,nginx会忽略tcp_nopush参数,然后强制使用tcp_nodelay发送

因此tcp_nopush和tcp_nodelay可以一起设置,性能更高。

六、nginx静态资源压缩:Gzip模块指令

一个常识:传输10M的文件和传输1M的文件,肯定是1M的效率更高。

因此,相同的文件,如果我们能进行“压缩 ”,实际上变相的就是提高了效率

压缩实际上我们需要使用到3个模块:

  • ngx_http_gzip_module模块
  • ngx_http_gzip_static_module模块
  • ngx_http_gunzip_module模块

七、ngx_http_gzip_module模块指令

该模块在nginx安装的时候内置到nginx的安装环境中,即我们可以直接使用该模块下的指令。

1.gzip指令

gzip:该指令用于开启或关闭gzip功能

#语法
gzip on|off;

#默认
gzip off;

#位置
http,server,location

注意,只有gzip指令为打开状态,该模块下后续的指令才会生效。

2.gzip_types指令

gzip_types:该指令可以根据相应页的MIME类型选择性的开启gzip压缩功能

#语法
gzip_types mime-type...;

#默认
gzip_types text/html;

#位置
http,server,location

所选择的值可以在mime.types文件中查找,也可以使用*来代表所有:

注:可能需要include mime.types;

3.gzip_comp_level指令

gzip_comp_level:该指令用于设置gzip压缩程度,级别从1-9,1表示压缩程度最低效率最高,9表示压缩程度最高效率最低

#语法
gzip_comp_level level;

#默认
gzip_comp_level 1;

#位置
http,server,location

4.gzip_vary指令

gzip_vary:设置gzip进行压缩发送是否携带“Vary:Accept-Encoding”头部的响应头。主要是告诉接收方,所发送的数据经过了gzip压缩处理

#语法
gzip_vary on|off;

#默认
gzip_vary off;

#位置
http,server,location

5.gzip_buffers指令

gzip_buffers:处理请求压缩的缓冲区数量和大小

#语法
gzip_buffers number size;

#默认
gzip_buffers 32 4k | 16 8k;

#位置
http,server,location

其中,number指定nginx服务器向系统申请缓存空间个数,size指每个缓存空间的大小。主要实现的是申请number个每个大小为size的内存空间。

这个值的设定一般会和服务器的操作系统有关,所以不建议设置,采用默认即可

6.gzip_disable指令

gzip_disable:针对不同种类客户端发起的请求,可以选择性地开启和关闭gzip功能

#语法
gzip_disable regex...;


#位置
http,server,location

regex:根据客户端的浏览器标志(user-agent)来设置,支持正则表达式。指定的浏览器标志不使用gzip。该指令一般用来排除一些明显不支持gzip的浏览器

gzip_disable "MSIE [1-6]\.";
gzip_disable "Mozilla/5.0.*";

7.gzip_http_version指令

gzip_http_version:指定使用gzip的http最低版本,该指令一般采用默认

#语法
gzip_http_version 1.0|1.1;

#默认
gzip_http_version 1.1;

#位置
http,server,location

8.gzip_min_length指令

gzip_min_length:该指令针对传输数据的大小,可以选择性的开启和关闭gzip功能

#语法
gzip_min_length length;

#默认
gzip_min_length  20;

#位置
http,server,location

nginx 计量大小的单位:bytes/kb/M。例如:1025,10k,10K,1m,1M

对于一些数据不大的,压缩效果也不明显。所以我们需要根据文件大小选择是否压缩。相应的页面大小可以通过头信息中的“Content-Length”来获取,但是如果使用了Chunk编码动态压缩,该指令会被忽略。建议设置为1K以上

9.gzip_proxied指令

gzip_proxied:该指令设置是否对服务端返回的结果进行gzip压缩。跟反向代理相关。

#语法
gzip_proxied off|expired|no-cache|no-store|private|no_last_modified|no_etag|auth|any;

#默认
gzip_proxied off;

#位置
http,server,location

注:
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:无条件启用压缩

八、gzip压缩功能的实例配置

1.先上传一个jquery.js的文件 ,路径如图

2.

#配置gzip相关的配置文件
cd /usr/local/nginx/conf/
vim nginx_gzip.conf

############################################
gzip on;
gzip_types *;
gzip_comp_level 6;
gzip_min_length 1024;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_vary on;
gzip_disable "MSIE [1-6]\."
gzip_proxied off;
############################################

#配置nginx的配置文件
vim nginx.conf

############################################
#我们这里只是修改了http下面的一些内容,其他不变
http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    tcp_nopush     on;
    tcp_nodelay    on;

    keepalive_timeout  65;

   include nginx_gzip.conf;  
############################################

九、ngx_http_gzip_static_module模块指令:解决Gzip和sendfile共存问题

1.问题

如果我们开启sendfile,从磁盘上拷贝的文件就会直接从内核缓冲区发送到socket缓冲区,不经过用户区,直接内核区流转。

但是如果开启gzip,就会进行压缩。可是压缩就需要去用户区进行,因此会有冲突。

2.解决思路

内核区读取的时候就别读取原文件,而是直接读取压缩文件,也就是说,保存一份压缩文件

3.gzip_static指令

gzip_static:检查与访问资源同名的.gz文件时,response中以gzip相关的header返回.gz文件的内容。

#语法:on会判断浏览器是否支持,always不判断,直接发送给浏览器
gzip_static on|off|always;

#默认
gzip_static off;

#位置
http,server,location

4.导入ngx_http_gzip_static_module模块

因为nginx没有默认导入ngx_http_gzip_static_module模块,因此需要单独导入,不然使用gzip_static指令指令会报错。

#将原来的nginx配置文件做个备份
cd /usr/local/nginx/sbin/
mv nginx nginxold

#清除之前编译的内容
cd /usr/local/nginx/core/nginx-1.16.1/
make clean

#使用configure来配置参数
./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

#将生成的nginx复制到sbin下
cp objs/nginx /usr/local/nginx/sbin/

#执行更新命令
make upgrade


5.测试

#压缩jquery.js
cd /usr/local/nginx/html/
gzip jquery.js


#关闭gzip
cd /usr/local/nginx/conf/
vim nginx_gzip.conf

##################
gzip off;
##################

#编辑nginx.conf
vim nginx.conf

######################
gzip_static on;
######################

#重启nginx
systemctl restart nginx

#测试,成功
#如果不设置gzip_static ,直接通过gzip的方式去查询,因为jquery.js已经被压缩,会报404
http://192.168.210.146/jquery.js

十、 静态资源的缓存处理

缓存大火应该都知道,缓存分客户端缓存服务端缓存

客户端缓存:浏览器缓存

服务端缓存:nginx,redis,memcached

1.浏览器缓存的执行过程

先回顾一下http协议中和缓存相关的字段:

Expires 缓存过期的日期和时间
Cache-Control 设置和缓存相关的配置信息
Last-Modified 请求资源最后修改时间
ETag 请求变量的实体标签的当前值,比如文件的MD5zh

浏览器查询,如果没有直接查询服务端。

如果Last-Modified没有过期,直接返回缓存,这叫强缓存。

如果Last-Modified过期,查询服务器ETag是否发生变化,未发生变化,直接返回缓存,这叫若缓存。

2.浏览器缓存相关指令

(1)expires指令

expires:该指令用来控制页面缓存的作用。可以通过该指令控制http应答中的“Expires”和“Cache-Control”

#语法
方法一:expires [modified] time;
方法二: expires epoch|max|off;

#默认
expires off;


#位置
http,server,location

#注:
time:可以是整数也可以是负数,指定过期时间。如果是负数,Cache-Control则为no-cache,则Cache-Control的值为max-age=time

epoch:指定Expires的值为1970-01-01 00:00:00,Cache-Control的值为no-cache

max:指定Expires的值为2037-12-31 23:59:59,Cache-Control的值为10年

off:不缓存

(2)add_header指令

add_header:添加指定的响应头和响应值

#语法
add_header name value [always];

#位置
http,server,location

对于name为Cache-control的响应头,对应响应值如下:

  • must-revalidate:可缓存但必须再向源服务确认
  • no-cache:缓存前必须确认其有效性
  • no-store:不缓存请求或响应的任何内容
  • no-transform:代理不可更改媒体类型
  • public:可向任意方提供响应的缓存
  • private:仅向特定用户返回响应
  • proxy-revalidate:要求中间缓存服务器对缓存的响应有效性再次确认
  • max-age=<秒>:响应最大Age值
  • s-maxage=<秒>:公共缓存服务器响应的最大Age值

十一、nginx的跨域问题

1.同源策略

浏览器的同源策略:是一种约束,是浏览器最核心也是最基本的安全功能。如果浏览器少了同源策略,则浏览器的正常功能可能都会受到影响。

同源:协议,ip,端口相同视为同源

2.跨域问题

有两台服务器A,B。如果从服务器A的页面发送异步请求到服务器B获取数据,如果服务器A和服务器B不满足同源策略,则会出现跨域问题

3.解决方案

#允许跨域访问的源地址信息,可以匹配多个ip+端口(逗号分隔),也可以使用*
add_header Access-Control-Allow-Arigin *;

#允许跨域访问的请求方式,逗号分隔
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE;

十二、静态资源防盗链

1.什么是资源盗链

资源盗链指的是此内容不在自己服务器上,而是通过技术手段,绕过别人的限制将别人的内容放到自己页面上展示。就是偷别人的页面展示在自己页面上。

2.防盗链的实现原理

HTTP头信息有一个Referer,当浏览器向web服务器发送请求的时候,一般都会带上Referer,来告诉浏览器该网页是从哪个页面链接过来的。后台服务器可以根据获取到的这个Referer信息来判断是否为自己信任的网站地址,如果是就放行,如果不是就返回403。

3.具体实现:valid_referers指令

valid_referers:nginx会通过查看referer自动和valid_referers后面的内容进行匹配,成功就将$invalid_referer置为0,否则置为1

#语法
valid_referers none|blocked|server_names|string...

#位置:
server,location

注:
none:如果Header中的Referer为空,允许访问

blocked:在Header中的Referer不为空,但是该值被防火墙或代理进行伪装过,如不带"http://"等协议头的资源允许访问

server_names:指定具体的域名或ip

string:可以支持正则表达式和*的字符串,如果正则表达式需要~开头表示

示例写法:

location /images {
    valid_referers none block www.baidu.com;
    if ($invalid_referer){
        return 403;
    }
    root html;
}

十三、打赏请求

如果本篇博客对您有所帮助,打赏一点呗,谢谢了呢~

猜你喜欢

转载自blog.csdn.net/qq_40594696/article/details/119911815