Nginx-入门

本文对Nginx进行了基本介绍,并描述了一些可以使用它完成的简单任务。假设已经安装了Nginx,如果没有,请参阅“Nginx-简介”。本博文介绍了如何启动和停止Nginx以及重新加载其配置,解释了配置文件的结构,并描述了如何设置Nginx以提供静态内容,如何将Nginx配置为代理服务器以及如何将其与FastCGI应用程序相连接。

启动、停止和重新加载配置

nginx -s <signal>

signal可以是以下信号之一:

  • stop: 快速关机
  • quit: 正常关机
  • reload: 重新加载配置文件
  • reopening: 重新打开日志文件

如果要停止Nginx进程,等待工作进程完成当前请求,可以执行以下命令:

nginx -s quit

在诸如kill应用程序等Unix工具的帮助下,也可以向Nginx进程发送信号。在这种情况下,一个信号被直接发送到指定进程ID的进程。Nginx主进程的ID在默认情况下,被写入在/usr/local/nginx/logs或者/var/run目录下的nginx.pid文件当中。如果Nginx的主进程ID为1628,要发送退出信号,优雅的关闭Nginx,我们可以这样:

nginx -s QUIT 1628

配置文件的结构

Nginx由模块组成,模块由配置文件中指定的指定控制。指令分为简单指令块指令。一个简单的指令由名称和参数组成,用空格分割,以分号结束。块指令具有与简单指令相同的结构,但不是分号,而是一组由大括号包围的附加指令。如果一个块指令可以在大括号中包含其他指令,那么它被称为上下文(例如:events、http、server和location)

任何放置在上下文外部的配置文件中的指令被认为是在主上下文中。eventshttp指令驻留在主上下文中,server驻留在http当中,location驻留在server当中。

其中“#”后面都代表是注释内容

顶级上下文有:

  • events: 处理常规连接
  • http: http请求
  • mail: 邮件
  • stream: TCP和UDP

在每个http上下文中,都包含一个或多个server块来定义控制请求处理的虚拟服务器。对于http上下文,每个server指令控制对特定域或IP地址上的资源请求的处理。每个server上下文中包含一个或多个location块来处理特定的Uri集。对于mail或者stream上下文,server指令分别控制到达特定TCP端口或UNIX套接字的通信处理。

通常子上下文继承父上下文中包含的指令的设置。一些指令可以出现在多个上下文当中,在这种情况之下,子上下文中的指令会覆盖父上下文中的同名指令。

提供静态内容

Web服务器的一项重要任务是分发文件。首先,我们先做一些准备工作,创建/user/image目录,并放置一个favorite.png图片。接下来,我们来修改一下/etc/nginx/sites-enabled目录下的default文件(此文件安装Nginx完后存在),在server上下文中添加一个location块指令,如下:

location /image/ {
    root /user;
}

修改保存之后,重启Nginx。对于匹配的请求,会将URL添加到root指定指定的路径,即添加到/user中,形成/user/image/就是我们本地文件系统上所请求文件的路径。我们在浏览器中访问http://localhost/image/favorite.png就能正确定位到图片了!如果有多个location块,将匹配前缀最长的的那个!其中root指令指定目录!

如果某些功能无法正常工作,你可以查看/var/log/nginx/access.log/var/log/nginx/error.log文件来查找原因!

设置简单的代理服务器

Nginx的一个常见用法是将其设置为代理服务器,这意味着服务器接收请求,将其传递给代理服务器,从代理服务器检索响应并将其发送给客户机。我们将配置一个基本的代理服务器,它使用本地目录中的文件夹来处理图像请求,并将所有请求发送到服务器中。在本例中,这两个服务器定义在一个Nginx实例中,如下:

server {
    listen 8080;
    root /user/data;
    location / {
        index index.html;
    }
}

这是一个简单的服务器,它监听端口8080(如果没有指定listen指令,将默认监听80端口),并将所有的请求映射到本地文件系统上的/user/data目录。需先创建该目录,并将index.html文件放置在该目录当中,否则请求将会引发404错误!

注意,当服务请求的location块不包含root指令时,就会使用上下文中的root指令!

下面,我们将修改一下配置,将成为代理服务器配置,如下:

server {
    listen 80;
    location / {
        proxy_pass http://localhost:8080;
    }
    location /image/ {
        root /user;
    }
}

在第一个location块中,使用proxy_pass指令与参数中的协议、代理服务器的名称和端口放在一起。我们还可以对location做一些正则匹配,如下:

location ~ \.(png|jpg|gif)$ {
    root /user;
}

如此,请求匹配所有以.gif.jpg.gif结尾的Uri。正则表达式的前面应该加上~,表示将使用正则表达式进行匹配!

设置FastCGI代理

Nginx可用于将请求路由到FastCGI服务器,FastCGI服务器运行各种框架和编程语言(如PHP)构建的应用程序。使用FastCGI服务器最基本的Nginx配置包括使用fastcgi_pass指令替代proxy_pass指令,使用facgi_param指令设置传递给FastCGI服务器的参数。假设FastCGI服务器可以在localhost:9000上访问。以上一节中的代理配置为基础,将fastcgi_pass指令替代proxy_pass指令,并将参数更改为localhost:9000。在PHP中,SCRIPT_FILENAME参数用于确定脚本,QUERY_STRING参数用于传递请求参数。配置如下:

server {
    location / {
        fastcgi_pass localhost:8080;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param QUERY_STRING $query_string;
    }
    location ~ \.(png|jgp|gif)$ {
        root /user;
    }
}

这将设置一个服务器,通过FastCGI协议将静态图像请求外的所有请求路由到localhost:9000上运行的代理服务器!

基于名称的虚拟服务器

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只检测请求的标头字段“Host”以确定将请求路由到哪个服务器。如果其值与任何服务器都不匹配,或者请求根本不包含此标头字段,则Nginx会将请求路由到该端口的默认服务器。在上面的配置当中,默认服务器是第一个服务器,这是Nginx的标准默认行为。也可以在listen指令中使用default_server参数设置哪个服务器应该是默认的,如下:

server {
    listen 80 default_server;
    server_name example.net www.example.net;
}

值得注意的是,default_server是侦听端口的属性,而不是服务器名称的属性。自0.8.21版本以来,default_server就可以使用了,但是在更早的版本前,应使用default参数

如何防止未定义的服务器名称处理请求

如果不允许不带“主机”标头字段的请求,则可以定义仅丢弃请求的服务器:

server {
    listen 80;
    server_name "";
    return 444;
}

在这里,服务器名称设置为空字符串,该字符串将匹配没有“Host”头字段的请求,并且返回特殊的Nginx的非标准代码444,以关闭连接。自从版本0.8.48开始,这是服务器名称的默认设置,因此server_name可以省略。

基于名称和基于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地址和端口。然后,它根据与IP地址和端口匹配的server块的server_name指令检测请求的“Host”标头字段。如果找不到服务器名称,则默认服务器将处理该请求。例如,192.168.1.1:80端口上接收到的请求将由192.168.1.1:80端口的默认服务器(即第一台服务器)处理。

一个简单的PHP站点配置

现在让我们看一下Nginx处理一个典型的、简单的PHP站点的请求,如下:

server {
    listen 80;
    server_name example.org www.example.org;
    root /data/www;
    location / {
        index index.html index.php;
    }
    
    location ~* \.(png|jpg|gif)$ {
        expires 30d;
    }
    
    location ~ \.php$ {
        fastcgi_pass localhost:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

无论列出的顺序如何,Nginx都会首先搜索文字字符串所给出的最特定的前缀location。在上面的配置当中,唯一的前缀location是“/”,因为它匹配任何请求,所以它将被用作最后的手段。然后Nginx按照配置文件中列出的顺序检查正则表达式给出的location。第一个匹配的表达式将停止搜索,Nginx将使用这个location。如果没有正则表达式的匹配请求,则Nginx使用前面找到的最特定的前缀的location

注意,所有类型的location只检测请求的Uri部分,没有参数。这样做是因为查询字符串中的参数可能以几种方式给出,如下:

/index.php?user=john&page=1
/index.php?page=1&user=john

此外,任何人都可以在查询字符串中请求任何东西:

/index.php?page=1&something+else&user=john

现在让我们看一下上面配置中如何处理请求:

  • 请求logo.gif首先与前缀location“/”匹配,然后与正则表达式\.(png|jpg|gif)$匹配,因此,请求由后一个location匹配。使用伪指令root /data/www将请求映射到文件/data/www/logo.gif,然后将文件发送到客户端
  • 请求index.php也首先与前缀location“/”匹配,然后与正则表达式\.php$匹配。因此,请求由后一个location匹配,并且请求被传递到了localhost:9000上侦听的FastCGI服务器上。fastcgi_param指令将FastCGI参数SCRIPT_FILENAME设置为/data/www/index.php,作为FastCGI的服务器执行文件。变量document_root等同于root指令的值,变量fastcgi_script_name等同于请求的Uri,即index.php.
  • 请求about.html仅与前缀location“/”匹配,因此在该location进行处理。使用伪指令root /data/www将请求映射到文件/data/www/about.html,然后将文件发送到客户端
  • 处理请求/更为复杂,它仅与前缀location“/”匹配,因此由该location处理。然后index指令根据其参数root /data/www指令检测文件的存在。如果文件/data/www/index.html不存在,但是文件/data/www/index.php存在,则该指令内部将重定向到index.php,并且Nginx将再次搜索location,就好像请求是由客户端发送的一样。如前所述,重定向的请求最终将由FastCGI服务器处理

在上面栗子当中,我们看到请求FastCGI服务器时,需要使用fastcgi_pass替代proxy_pass,其中uwsgiSCGImemcachedgRPC服务也分别使用uwsgi_passscgi_passmemcached_passgrpc_pass指令替代proxy_pass

发布了158 篇原创文章 · 获赞 115 · 访问量 52万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章