什么是 Nginx?
Nginx (Engine X)是一个轻量级的Web服务器 、反向代理服务器及电子邮件(IMAP/POP3)代理服务器、高性能的HTTP服务器,它以高稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。
什么是反向代理?
反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 internet 上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器,在做HTTP反向代理和负载均衡时,特意要注意开启HTTP长连接的支持。
Web服务器
Apache应该为大家所熟知,而Nginx就是类似Apache的提供静态网页的Web服务器,相比于Apache的多进程多线程的并发模型,而Nginx是基于事件的异步IO的并发模型,性能更好,而且Nginx是一个轻量级的服务器。
针对于Nginx的介绍我们就不过多赘述了,现在开始针对于Nginx的配置进行相关的介绍说明。
Nginx原理简介
Nginx有一个主进程(Master)和几个工作进程(Worker),采用了基于事件模型和依赖于操作系统的机制来有效地在工作进程之间分配请求。
- 主进程(Master)目的是读取和评估配置,并维护工作进程。
- 工作进程(Worker)对请求进行处理,工作进程的数量可在配置文件中定义,并且可以针对给定的配置进行修改,或者自动调整到可用 CPU 内核的数量 worker_processes。
Nginx模块化机制
Nginx是模块化的系统,整个系统是分成一个个模块的,每个模块负责不同的功能。在上面的configure指令中带了很多参数,就是在这里编译之前可以加入某些模块或去掉某些模块的。我们会把要用的模块再源码编译的时候就编译进入到Nginx了,那要怎么用这些模块呢?那就得通过配置文件来实现。接下来我们就开始使用入门配置实践指南阶段,进行学习。
入门配置说明指南
配置文件决定了Nginx及其模块的工作方式。默认情况下,配置文件名为 nginx.conf,默认安装目录为 /usr/local/nginx/conf,/etc/nginx 或 /usr/local/etc/nginx 中,整个配置文件都是由指令来控制的。nginx也有自己内置的指令,比如events, http, server, 和 location等,下面会提到的。
Nginx文件配置说明
首先,我们先不考虑复杂的配置,仅仅是完成一个http反向代理,Nginx.conf配置文件如下:
注:conf/nginx.conf 是 nginx 的默认配置文件,你也可以使用 nginx -c 指定你的配置文件。
Nginx文件书写规则
Nginx是由配置文件中指定的指令控制模块组成。指令可分为简单指令和块指令。
简单指令
一个简单的指令是由空格分隔的名称和参数组成,并以分号 ; 结尾。
块指令
块指令具有与简单指令相同的结构,但不是以分号结尾,而是以大括号{}包围的一组附加指令结尾。
指令上下文
如果块指令的大括号内部可以有其它指令,则称这个块指令为上下文(例如:events,http,server 和 location)。
主上下文
配置文件中被放置在任何上下文之外的指令都被认为是主上下文 main。events 和 http 指令在主 main 上下文中,server 在 http 中,location 又在 server 中。
注释
井号 # 之后的行的内容被视为注释。
入门配置实战案例
配置文件大致格式结构
在这个文件中,在这个文件中,主要由三个部分组成:events,http、mail。
events { } http { } mail { } 复制代码
和块之间还可以嵌套的。例如http下面可以放server。
http { server { } } 复制代码
实现转图片和html的映射路由
需求介绍
首先根据请求,将提供来自不同的本地目录的文件: /data/htmls(可能包含 HTML 文件)和 /data/images(包含图片)。
配置实现
- 创建 /data/htmls目录并且将包含index.html文件放入。之后,创建 /data/images目录然后放一些图片进去。
- 打开这个nginx.conf这个配置文件,我们首先通过http块指令嵌入一个块指令server。
http { server { } } 复制代码
包含几个由监听listen端口和服务器域名server names区分的server块指令。
当Nginx决定由哪个server来处理请求,它会根据 server 块中定义的 location 指令的参数来检验请求头中指定的URI。
添加如下 location 块指令到 server 块指令中:
location / { root /data/htmls; } 复制代码
location块指令
- 指定 / 前缀与请求中的 URI 相比较。
对于匹配的请求,URI 将被添加到根指令 root 中指定的路径,即 /data/htmls,以形成本地文件系统上所请求文件的路径。
如果有几个匹配上的 location 块指令,Nginx将选择具有最长前缀的 location 块。上面的位置块提供最短的前缀,长度为 1,因此只有当所有其它 location 块不能匹配时,才会使用该块。
接下来,添加第二个 location 指令快:
location /images/ { root /data; } 复制代码
以 /images/ 为开头的请求将会被匹配上(虽然 location / 也能匹配上此请求,但是它的前缀更短)
最后的server块指令
server { location / { root /data/htmls; } location /images/ { root /data; } } 复制代码
结论:监听标准 80 端口并且可以在本地机器上通过 http://localhost/ 地址来访问的有效配置。响应以 /images/ 开头的URI请求,服务器将从 /data/images 目录发送文件,由于使用了标准 80 端口,所以没有指定 listen 指令
案例结论介绍说明
例如,响应http://localhost/images/example.png 请求,nginx 将发送 /data/images/example.png 文件。如果此文件不存在,nginx 将发送一个404错误响应。不以 / images/ 开头的 URI 的请求将映射到 /data/htmls 目录。例如,响应 http://localhost/some/example.html 请求,nginx 将发送 /data/www/some/example.html 文件。
要让新配置立刻生效,如果nginx尚未启动可以启动它,否则通过执行以下命令将重新加载配置信号发送到 nginx 的主进程:
nginx -s reload 复制代码
如果运行的效果没有在预期之中,您可以尝试从 /usr/local/nginx/logs 或 /var/log/ nginx 中的 access.log 和 error.log 日志文件中查找原因。
案例实践配置简单的代理服务器
需求案例
Nginx的一个常见用途是作为一个代理服务器,作用是接收请求并转发给被代理的服务器,从中取得响应,并将其发送回客户端,我们会将图片请求提供的文件来自本地目录,并将所有其它请求发送给代理的服务器。
首先,通过向 nginx 的配置文件添加一个 server 块来定义代理服务器,其中包含以下内容:
server { listen 8080; root /data/up1; location / { } } 复制代码
- listen:监听8080端口的简单服务器,并将所有请求映射到本地文件系统上的 /data/up1 目录。
- root:代表着全局默认点,当location中没有配置root,则会选用/data/up1这个path。
创建此目录并将 index.html 文件放入其中。
注意,root 指令位于 server 上下文中。当选择用于处理请求的location块自身不包含root指令时,将使用此 root 指令。
在之前的服务器配置基础上进行修改,使其成为代理服务器配置。在第一个 location 块中,使用参数指定的代理服务器的协议,域名和端口( http://localhost:8080)放置在proxy_pass 指令处:
server { location / { proxy_pass http://localhost:8080; } location /images/ { root /data; } } 复制代码
- proxy_pass:设置对应的下游服务请求url根目录地址。
修改使用了/images/前缀将请求映射到/data/images目录下的文件的第二个location块,使其与图片文件扩展名的请求相匹配。修改后的 location 块如下所示:
location ~ \.(gif|jpg|png)$ { root /data/images; } 复制代码
该参数是一个正则表达式,匹配所有以.gif,.jpg 或 .png 结尾的 URI。正则表达式之前应该是 ~。相应的请求将映射到 /data/images 目录。
当Nginx选择一个location块来提供请求时,它首先检查指定前缀的 location 指令,记住具有最长前缀的 location,然后检查正则表达式。如果与正则表达式匹配,nginx 会选择此 location,否则选择更早之前记住的那一个。
代理服务器的最终配置如下:
server { location / { proxy_pass http://localhost:8080/; } location ~ \.(gif|jpg|png)$ { root /data/images; } } 复制代码
此 server 将过滤以 .gif,.jpg 或 .png 结尾的请求,并将它们映射到 /data/images 目录(通过向 root 指令的参数添加 URI),并将所有其它请求传递到上面配置的代理服务器。
案例配置-基于Host名称的虚拟服务器
Nginx首先要决定哪个服务器应该处理请求。让我们从一个简单的配置开始,三个虚拟服务器都监听在端口*:80:
server { listen 80; server_name example.org www.example.org; ... } server { listen 80; server_name example.net www.example.net; ... } 复制代码
在这个配置中,Nginx仅仅检验请求header中的”Host”域来决定请求应该路由到哪个服务器。
如果它的值不能匹配任何服务器,或者请求完全没有包含这个header域,那么nginx将把这个请求路由到这个端口的默认服务器。在上面的配置中,默认服务器是第一个 - 这是nginx标准的默认行为。也可以通过listen指令的default_server属性来显式的设置默认服务器,例如下面配置:
server { listen 80 default_server; server_name example.net www.example.net; ... } 复制代码
default_server 参数从版本0.8.21开始可用,在更早的版本中要使用default参数。
防止使用未定义的服务器名称来处理请求
如果容许请求没有”Host” header 域,放弃这些请求的服务器可以定义为:
server { listen 80; server_name ""; return 444; } 复制代码
服务器名称被设置为空字符串,这样将匹配没有”Host”header域的请求, 并返回一个特殊的nginx的非标准码404,然后关闭连接。
基于名称和基于IP混合的虚拟服务器
让我们看一下更复杂的配置,有一些虚拟服务器监听在不同的地址:
server { listen 192.168.1.1:80; server_name example.org www.example.org; ... } server { listen 192.168.1.1:80; server_name example.net www.example.net; ... } 复制代码
在这个配置中,nginx首先通过server块的listen指令检验请求的IP地址和端口。然后在通过server块的server_name入口检验请求的”Host”header域。如果服务器名称没有找到,请求将被默认服务器处理。
例如,在端口192.168.1.1:80接收到的去www.example.com的请求将被端口192.168.1.1:80的默认服务器处理。。
默认服务器是监听端口的属性,并且不同的端口可以定义不同的默认服务器:
server { listen 192.168.1.1:80; server_name example.org www.example.org; ... } server { listen 192.168.1.1:80 default_server; server_name example.net www.example.net; ... } 复制代码
要使新配置立即生效,请将重新加载配置文件信号(reload)发送到 nginx,如前几节所述。