什么是 Nginx?

Nginx (Engine X) 是一个轻量级的 Web 服务器 、反向代理服务器及电子邮件(IMAP/POP3)代理服务器、高性能的 HTTP 服务器,它以高稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名

什么是反向代理?

反向代理(Reverse Proxy)方式是指以代理服务器来接受 internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 internet 上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器,在做 HTTP 反向代理和负载均衡时,特意要注意开启 HTTP 长连接的支持。

nginx 命令 linux_Nginx

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(包含图片)。

配置实现

  1. 创建 /data/htmls 目录并且将包含 index.html 文件放入。之后,创建 /data/images 目录然后放一些图片进去。
  2. 打开这个 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;    ...}server {    listen      80;    server_name example.com www.example.com;    ...}

在这个配置中,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;    ...}server {    listen      192.168.1.2:80;    server_name example.com www.example.com;    ...}

在这个配置中,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;    ...}server {    listen      192.168.1.2:80 default_server;    server_name example.com www.example.com;    ...}

世间非静土,各有各的苦