默认的配置文件就在/usr/local/nginx/conf/nginx.conf
。
如果找不到配置文件也没关系,我们有两种方式来查看配置文件:①
使用ps
命令查看
ps -ef | grep nginx
②
使用-t
命令查看
/usr/local/nginx/sbin/nginx -t
user nobody; # main 级别配置,nginx核心功能
events {
use epoll; # events级别配置, nginx事件机制
}
http { # http 级别 nginx的http核心模块
server { # server 级别,一个server代表一个虚拟主机
location {
# location级别, 一个location代表一类url
}
}
}
http {
server { # server1
server_name my.first.server.com
root /root/server1;
location / { #location1
}
location /img { #location2
root /root/img;
}
}
}
那么在location2
中的root
会覆盖server1
中的root
,而location1
中由于没有root
,所以会继承它的上一层级的root
。
在nginx
中,下一层级如果没有配置指令的话,会继承上一层级的同一个配置的值。
user指令
我们知道,操作系统中的所有资源都具有所属者以及其他各种访问权限(强大的Linux
也不例外~)。这种权限控制可以让操作系统变得很安全,防止黑客
破坏我们的系统。
worker_processes 指令
我们前面说过,Nginx
是一个Master-Worker
的工作模式。Nginx
在启动之后会生成一个master
进程,master
不处理请求,而是生成和管理worker
进程,worker
进程主要负责干活(处理请求)。
那么大家可能要问了?这个值应该设置为多大呢?是不是这个值越大越好?当然不是了,我们看一下大神们给出的建议:
nginx doesn't benefit from more than one worker per CPU.
If Nginx is doing CPU-intensive work such as SSL or gzipping and you have 2 or more CPUs/cores, then you may set worker_processes to be equal to the number of CPUs or cores.
所以worker_processes
的值并不是越多越好,最好是和我们服务器CPU
核数量一样。Nginx
提供了一个默认的auto
值就是这样的原理。
Nginx
作为一个广泛应用的Web
服务器,支持三种形式的虚拟主机配置:
- 基于端口号的主机配置
- 基于
ip
的主机配置 - 基于域名的主机配置
基于端口号的主机配置
所谓基于端口的主机配置就是多个虚拟主机的ip
地址相同,但是他们的端口不同,我们可以通过端口号来访问不同的虚拟主机。
我们以8081
, 8082
,8083
三个端口为例来了解这种配置。
为每一个端口号创建目录。
1.
在/usr/local/nginx/html/
目录下面创建port
子目录2.
在port
下面创建8081
,8082
,8083
三个子目录、3.
每个子目录分别创建各个端口的index
文件
修改配置文件
修改/usr/local/nginx/conf
目录下面的nginx.conf
文件,如下:
基于IP
的虚拟主机
所谓基于IP
的虚拟主机就是将虚拟主机绑定到不同的IP
地址。我们可以通过不同的IP
地址访问不同的虚拟主机。
配置IP
一般情况下,我们自己的电脑都只会有最多两个网卡,这个时候我们可以使用ifconfig
命令来增加几个虚拟网卡来完成本次实验。如下:
基于域名的虚拟主机
所谓基于域名的虚拟主机是非常广泛的一种使用方式,绝大多数公司都是使用该种方式配置的虚拟主机。我们对三个域名都监听了相同的IP
地址和端口号。
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last
如果我们请求的path
是/download/xunlei/media/movie.flv
,那么实际的请求资源就是/download/xunlei/mp3/movie.mp3
。
return
命令
和其他的编程语言类似,return
就是直接返回,停止后续的处理直接返回。
rewrite
指令
其实本节中我重点想要讲解的是rewrite
指令,这个指令在平时的工作中经常的用到,但是很多人对该指令的理解都是片面的。
先看一下rewrite
的语法格式:
rewrite regex replacement [flag];
rewrite
指令是使用指定的正则表达式(上一节我们介绍过的哦~)regex
来匹配当前请求的URI
,如果匹配成功,则使用replacement
更改URI
。rewrite
指令按照它们在配置文件中出现的顺序执行(下面我们总结了rewrite
的执行顺序),可以使用flag
参数来控制指令的进一步处理。如果替换字符串replacement
以http://
,https://
或$scheme
开头,则停止处理后续内容,并直接重定向返回给客户端。
我们先从整体上看一下rewrite
的执行顺序,过程如下:
- 按照
rewrite
指令在server
中出现的顺序逐个执行,确定最终
的URI
。 - 循环执行下面的步骤:(上一步确定了
URI
)- 根据
URI
找到匹配的location
- 按
rewrite
指令在location
中出现的顺序逐个执行 - 如果上一步中对
URI
进行了重写,那么重复执行第2
步骤,最多重复执行10
次。
- 根据
rewrite
指令最让人难理解原因是flag
参数,特别是break
和last
这两个参数。
last:
停止处理当前的ngx_http_rewrite_module
的指令集,并开始搜索与更改后的URI
相匹配的location
。(这里的last
是持续,继续
的意思,而不是最后
)break:
停止处理当前的ngx_http_rewrite_module
指令集
上面是Nginx
官网上的解释,其实这里面有一个比较难以理解的地方,什么是当前
的ngx_http_rewrite_module
的指令集?大家如果知道了这个概念,其实这两个参数的区别就挺好理解的了。
在文章的开始我们说过,ngx_http_rewrite_module
模块实现了一个脚本引擎,脚本引擎执行的过程需要上下文,所有在同一个server
级别的ngx_http_rewrite_module
模块的指令共享同一个上下文。所有在同一个location
级别的ngx_http_rewrite_module
模块的指令共享同一个上下文。所以上面的当前
指的就是同一个上下文。ngx_http_rewrite_module
模块的指令集就是本文开头说的那几个。
location
的用法
location
是nginx
的一大利器,该指令可以让根据请求的URI
分别进行不同的处理,比如如果用户请求的是一个图片,那么需要到pic
目录下面寻找,如果请求的是视频,那么需要到video
目录下面寻找,这样我们就可以把不同类型的文件分开存储,方便了管理。
我们先来看一下location
的语法规则,非常的简单:
Syntax: location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
Default: —
Context: server, location
我把这几种情况进行了分类:
- 普通匹配(没有任何修饰符)
- 精确匹配(以”=”开头)
- 最长前缀匹配(以”^~”开头)
- 正则匹配
- 区分大小写的正则(以
~
开头) - 忽略大小写的正则(以
~*
开头)
- 区分大小写的正则(以
- 内部
location
(以@
开头)
匹配顺序
我在工作过程中发现有很多人对Location
的匹配顺序搞不清楚,所以这节课我就会以着重给大家分析一下如何根据用户请求的URI
进行Location
匹配。
上图是我画的一个流程图,从这个流程图中我们可以清晰的看到location
的匹配顺序。
从流程图中我们可以总结如下几点:
- 精确匹配的优先级最高。
- 如果没有精确匹配,那么就会对配置文件中的所有非正则
location
进行匹配,找到最长匹配。3. 如果最长匹配是以^~
开头,那么就返回该匹配结果。 - 对正则匹配逐个进行匹配,如果匹配成功,则返回正则
location
,如果不成功,则返回第2
步匹配的最长匹配结果。
划重点了:
- 第
2
步是要对所有的非正则location
都要进行匹配,也就是说,非正则匹配与location
出现的顺序无关- 第四步是对正则
location
逐个匹配,如果成功就直接返回,所有正则表达式结果与配置文件中出现的顺序有关系。
这里有两点小建议:
- 因为精确匹配的优先级最高,比如根域名这些经常被访问的
URI
建议使用精确匹配。 - 正则匹配与顺序有关,所以建议越详细的正则应该越靠前。