Nginx的主要配置
1、nginx文件结构
... #全局块
events { #events块
...
}
http #http块
{
... #http全局块
server #server块
{
... #server全局块
location [PATTERN] #location块
{
...
}
location [PATTERN]
{
...
}
}
server
{
...
}
... #http全局块
}
-
1、全局块:配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等。
-
2、events块:配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。
-
3、http块:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。
-
4、server块:配置虚拟主机的相关参数,一个http中可以有多个server。
-
5、location块:配置请求的路由,以及各种页面的处理情况。
2、nginx.conf 文件内容分析
/etc/nginx/nginx.conf
# 运行用户,默认是nginx,可以不进行设置
user nginx;
# Nginx进程,一般设置和cpu核数一样
worker_processes 1;
# 错误日志存放位置
error_log /var/log/nginx/error.log warn;
# 进程pid存放位置
pid /var/run/nginx.pid;
events {
# 单个后台进程的最大并发数
worker_connections 1024;
}
http {
# 文件扩展名和类型映射表
include /etc/nginx/mime.types;
# 默认的文件类型
default_type application/octet-stream;
# 设置日志模式(默认的、无须设置的combined日志格式设置)
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# nginx访问日志的存放位置
access_log /var/log/nginx/access.log main;
# 是否开启高效传输模式 on开启 off关闭
sendfile off;
# 减少网络报文段的数量
#tcp_nopush on;
# 保持连接的时间,也叫超时时间
keepalive_timeout 65;
# 开启gzip压缩模式
#gzip on;
# 包含的子配置项的位置和文件
include /etc/nginx/conf.d/*.conf;
}
3、常用配置
(1)、一个站点配置多个域名
server {
listen 80;
server_name aaa.cn bbb.cn;
}
(2)、反向代理,负载均衡
将80端口进来的请求代理到192.168.0.1和192.168.0.2的服务上。
http
{
#流的配置,用于负载均衡
upstream xxx
{
server 192.168.0.1;
server 192.168.0.2;
}
server
{
listen 80;
server_name 域名或IP;
location /
{
root html;
index hello.html;
#配置反向代理
proxy_pass http://xxx;
#避免原ip统计不到
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
(3)、动静分离
存粹的将静态文件部署在一台独立的服务器上,使用单独的域名,与动态请求区分开。(主流推崇)
当前的目录情况:
./conf.d/my_nginx.conf 配置情况:
server
{
listen 80;
server_name 独立的域名或IP;
#解决目录中文乱码问题
charset utf-8,gbk;
location /html
{
root /usr/docker/myNginx;
index hello.html;
}
location /images
{
root /usr/docker/myNginx;
#Nginx默认是不允许列出整个目录的,打开需要加上
autoindex on;
}
}
测试结果:
访问图片,ip/imgaes
访问网页,ip/html
(4)、动静分离(指定资源格式 + 缓存)
http缓存概念梳理:
1、强制缓存(无HTTP请求,无需协商):
浏览器在加载资源的时候,会先根据本地缓存资源的header中的信息(Expires 和 Cache-Control)来判断是否需要强制缓存。如果命中的话,则会直接使用缓存中的资源。否则的话,会继续向服务器发送请求。
Http协议的cache-control和expires的常见取值及释义:
private(默认): 只能在浏览器中缓存, 只有在第一次请求的时候才访问服务器, 若有max-age, 则缓存期间不访问服务器。 public:可以被所有的用户缓存,包括终端用户和 CDN 等中间代理服务器。 no-cache: 需要进行协商缓存,发送请求到服务器确认是否使用缓存。 no-store:禁止使用缓存,每一次都要重新请求数据。 max-age(绝对):指我们的web中的文件被用户访问(请求)后的存活时间,是个相对的值。默认的max-age是由Expires算出来的,单位为秒。 expires(相对):头部字段提供一个日期和时间,响应在该日期和时间后被认为失效。 2、协商缓存(有HTTP请求,需协商):
①、协商缓存 Last-Modified/if-Modify-Since。
浏览器第一次发出请求一个资源的时候,服务器会返回一个last-Modify到hearer中 Last-Modify 含义是最后的修改时间。
当浏览器再次请求的时候,request的请求头会加上 if-Modify-Since,该值缓存的是之前返回的 Last-Modify。 服务器收到if-Modify-Since后,根据资源的最后修改时间(last-Modify)和该值(if-Modify-Since)进行比较。如果相等的话,则命中缓存,返回304,否则, 如果 Last-Modify > if-Modify-Since, 则会给出200响应,并且更新Last-Modify为新的值。
②、协商缓存 ETag/if-None-Match。
web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定),如果给定URL中的资源修改,则一定要生成新的Etag值。
浏览器再下一次加载的时候会向服务器发送请求,会将上一次返回的ETag值放到request header 里的 if-None-Match里面去,服务器端只要比较客户端传来的if-None-Match值是否和自己服务器上的ETag是否一致,如果一致说明资源未修改过,因此返回304,如果不一致,说明修改过,因此返回200。并且把新的Etag赋值给if-None-Match来更新该值。
Nginx默认开启last modified特性, 也可以在nginx.conf中添加以下配置, 主动控制:
location ~ .*\.(js|css)?$ {
root /usr/share/nginx/static;
if_modified_since off/exact/before; #off:关闭;exact:精准匹配才取缓存;before:时间之前的也可取缓存
}
Nginx1.7.3及以上的版本默认开启Etag特性, 但是和Last-Modified一样, 可以主动配置:
location ~ .*\.(js|css)?$ {
root /usr/share/nginx/static;
etag off/on;
}
同时存在Last-modify、etag、expires以及cache-control这个4个属性时, cache-control的优先级是最高的。
优先级:Cache-Control > Expires > Etag > Last-modify
max-age=xxx (xxx is numeric) 缓存的内容将在 xxx 秒后失效, 如果和Last-Modified一起使用时, 优先级更高
Nginx设置cache-control(例如设置max-age为30秒):
location ~ .*\.(js|css)?$ {
root /usr/share/nginx/static;
add_header Cache-Control "max-age=30";
}
通过 expires 参数设置,可以使浏览器缓存过期时间,减少与服务器之前的请求和流量。Expires的定义:是给一个资源设定一个过期时间,也就是说无需去服务端验证,直接通过浏览器自己确认是否过期即可,所以不会产生额外的流量。此方法仅适合不经常变动的资源使用。(不适用于频繁变动的资源)
#静态资源缓存设置
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$ {
root /usr/share/nginx/static; #static文件夹在Nginx目录下没有,需创建,和conf文件夹同级
expires 30d;
}
location ~ .*\.(js|css)?$ {
root /usr/share/nginx/static;
expires 30d;
#expires 30s; #30秒
#expires 30m; #30分钟
#expires 2h; #2个小时
#expires 30d; #30天
}
上述配置中的 30d ,表示在这30天内访问这些后缀的资源时,会发送一个请求,对比服务器该文件最后更新时间有没有变化,没有则不从服务器抓取,直接返回状态码304,如果有修改,则直接从服务器重新下载,返回状态码200。
(5)、静态缓存场景验证:
①、静态资源不缓存,每次都是重新获取。
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$ {
root /usr/share/nginx/static;
add_header Cache-Control no-store;
}
②、静态资源设置 Cache-Control 进行强缓存。
#静态资源缓存设置
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$ {
root /usr/share/nginx/static; #static文件夹在Nginx目录下没有,需创建,和conf文件夹同级
if_modified_since off;
etag off;
add_header Cache-Control max-age=60; #浏览器进行60s缓存。
}
首次加载:
换个浏览器tab页,在首次加载成功后的60s内访问:
超过60s,将需要重新从服务器加载资源。
③、静态资源设置 Expires 进行强缓存。
#静态资源缓存设置
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$ {
root /usr/share/nginx/static; #static文件夹在Nginx目录下没有,需创建,和conf文件夹同级
if_modified_since off;
etag off;
expires 120s; #浏览器进行120s缓存。
}
在Date和Expires显示的时间(显示的GMT为世界标准时间,而我国是东八区,即GMT+8)范围内,缓存有效,更换浏览器tab窗口访问不会重新加载服务器资源。
超出时间则会重新加载资源,重新计算Date和Expires。
④、静态资源设置 Etag 进行协商缓存。
#静态资源缓存设置
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$ {
root /usr/share/nginx/static; #static文件夹在Nginx目录下没有,需创建,和conf文件夹同级
if_modified_since off;
etag on;
}
首次加载,从服务器获取资源。
文件内容不变的前提下,第二次加载(etag值相同),读取缓存,响应码304。
文件内容变更后,第三次加载(etag值变更),重新请求服务器加载了服务器资源。
⑤、静态资源设置 if-Modify-Since 进行协商缓存。
#静态资源缓存设置
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$ {
root /usr/share/nginx/static; #static文件夹在Nginx目录下没有,需创建,和conf文件夹同级
if_modified_since exact; #Last-Modified 和 if-Modify-Since两者相等则取缓存值。
etag off;
}
首次加载,从服务器获取资源。
图片资源内容未变动的前提下,第二次加载(Last-Modified 和 if-Modify-Since两者相等),读取缓存资源,响应码304。
图片资源内容变动,第三次加载(Last-Modified 和 if-Modify-Since值不同),再次从服务器获取资源,并更新Last-Modified的值。
关于动静分离中使用缓存的思考,这里顺便推荐一篇知乎回答:
大公司里怎样开发和部署前端代码? - 张云龙的回答 - 知乎
4、nginx中location的规则
语法规则:
location [ = | ~ | ~* | ^~ ] /uri/ {… }
首先匹配 =,其次匹配^~,其次是按文件中顺序的正则匹配,最后是交给 /通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。
符号 | 含义 |
---|---|
= | = 开头表示精确匹配 |
^~ | ~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则~ /static/ /aa匹配到(注意是空格) |
~ | ~ 开头表示区分大小写的正则匹配 |
~* | ~* 开头表示不区分大小写的正则匹配 |
!~和!~* | !~ 和 !~*分别为区分大小写不匹配及不区分大小写不匹配的正则 |
/ | 用户所使用的代理(一般为浏览器) |
@ | 带有@的 location 是用来定义一个命名的 location,这种 location 不参与请求匹配,一般用在内部定向 |
匹配规则示例:
location = / {
#规则A
}
location = /login {
#规则B
}
location ^~ /static/ {
#规则C
}
location ~ \.(gif|jpg|png|js|css)$ {
#规则D
}
location ~* \.png$ {
#规则E
}
location !~ \.xhtml$ {
#规则F
}
location !~* \.xhtml$ {
#规则G
}
location / {
#规则H
}
location /test {
#规则I
try_files $uri $uri/ @custom
}
location @custom {
#规则I_2
}
那么产生的效果如下:
-
访问根目录/,比如:http://localhost/ 将匹配规则A
-
访问 http://localhost/login 将匹配规则B,http://localhost/register 则匹配规则H
-
访问 http://localhost/static/a.html 将匹配规则C
-
访问 http://localhost/a.gif ,http://localhost/b.jpg 将匹配规则D和规则E,但是规则D顺序优先,规则E不起作用,http://localhost/static/c.png 则优先匹配到规则C
-
访问 http://localhost/a.PNG 则匹配规则E,而不会匹配规则D,因为规则E不区分大小写。
-
访问 http://localhost/a.xhtml 不会匹配规则F和规则G,http://localhost/a.XHTML 不会匹配规则G,因为不区分大小写。规则F,规则G属于排除法,符合匹配规则但是不会被匹配到,属于逆向思维了。
-
访问 http://localhost/category/id/1111 则最终匹配到规则H,因为以上规则都不匹配,这个时候应该是nginx转发请求给后端应用服务器,比如FastCGI(php),tomcat(jsp),nginx作为反向代理服务器存在。
-
访问 http://localhost/test 则匹配到规则I,并通过@重定向到规则I_2。
评论区