[译]如何配置Nginx

image

原文地址: How to Configure NGINXphp

Nginx是一个轻量的、高性能、专为高并发设计的web服务器。css

Nginx一个鲜明的特色就是,可以高效的处理诸如HTML之类的媒体文件。Nginx采用异步事件驱动模型,以提供高负载下的可预测性能。html

动态内容通过Nginx透传给CGI、FastCGI或者其余的诸如Apache的web服务器,而后这些内容又返回给Nginx以分发给客户端。本文将使你熟悉基本的Nginx参数配置和规定。前端

指令(Directives)&块(Blocks)&上下文(Contexts)

全部的Nginx配置文件都位于/etc/nginx目录下,基本的也是最主要的配置文件是/etc/nginx/nginx.confnode

Nginx的配置项也被称之为指令。指令集合就是常说的或者上下文, 二者是相同的。nginx

以字符#开头的行是注释行,不会被Nginx所解析。指令行必须以分号;结尾,不然Nginx没法正确的加载配置文件,并抛出错误。web

如下截取自安装nginx时自带的配置文件/etc/nginx/nginx.conf。该文件开头有四个指令: user,worker_processes,error_log, pid。它们没有包含在任何指令块内,所以咱们称之为存在于主指令块内。eventshttp指令块是额外的指令配置块,它们也存在于主指令块内。正则表达式

你能够参考nginx官方配置文件来了解这些指令的含义,以及主指令块内的其余配置参数。bash

user   nginx;
    worker_processes   1;
    
    error_log    /var/log/nginx/error.log warn;
    pid          /var/run/nginx.pid
    
    
    events {
        ...
    }
    
    http {
        ...
    }
    
复制代码

http配置块

http配置块内包含着处理web通讯的指令,这些指令一般被成为通用指令,由于这些指令做用于全部nginx代理的站点服务。 能够查阅nginx官方配置文件来了解http配置块内的全部指令服务器

http {
        include     /etc/nginx/mime.type;
        default_type        application/octet-stream;
        
        log_format  main    '$remote_addr - $remote-user [$time_local] "$request" '
                            '$status $body_bytes_sent "$http_referer"'
                            '"$http_user_agent" "$http_x_forwarded_for"';
                            
                            
        access_log      /var/log/nginx/access.log   main;
        
        sendfile        on;
        #tcp_nopush on;
        
        keepalive_timeout       65;
        
        #gzip on;
        
        include     /etc/nginx/conf.d/*.conf;
        
    }
复制代码

Server配置块

上面的http配置块包含了一个include指令,它是用来告诉nginx站点的配置文件的位置

  • 若是你是用官方的nginx包安装的,那么会是像上面的那样include /etc/nginx/conf.d/*.conf。 用nginx代理的每一个站点都应该在目录/etc/nginx/conf.d下有本身的配置文件, 而且使用形如 example.com.conf的统一的命名规范。 没有被nginx代理的站点的配置文件应该被命名为example.com.conf.disabled
  • 若是你从Debian或者Ubuntu源上安装的nginx,这条指令会是这样的/etc/nginx/sites-enabled/*; sites-enabled文件夹下包含着站点配置文件的连接,这些文件存储在/etc/nginx/sites-available/文件下。 能够经过移除连接的方式达到禁用站点代理的目的。
  • 根据你的安装源,能够在/etc/nginx/conf.d/default.conf或者etc/nginx/sites-enabled/default 路径下找到默认的nginx配置例子

不管是何种安装源,每一个站点的配置文件都会包含一个server配置块,例如:

# /etc/nginx/conf.d/example.com.conf
    
    server {
        listen          80 default_server;
        listen          [::]:80 default_server;
        server_name     example.com www.example.com;
        root            /var/www/example.com;
        index           index.html;
        try_files $uri /index.html;
    }
复制代码

监听端口

listen 指令告诉nginx应该监听的http连接的主机名/IP/端口号。 default_server参数意味着,哪些80端口上的、不符合其余特定的监听声明的请求也会被该虚拟主机处理。第二个listen指令是基于IPv6的,行为与上一个IPv4一致.

命名的虚拟主机

server_name指令,容许一个IP地址代理多个域名,nginx代理服务器会根据收到的请求头来决定将请求转发给哪一个域名。

你应该为代理的每一个域名建立一个单独的配置文件,下面是对应的一些例子:

  1. 处理来自example.comwww.example.com的请求
# /etc/nginx/conf.d/example.com.conf

server_name     example.com www.example.com;
复制代码
  1. server_name指令的值也能够是通配符**.example.com.example.com这两个指令都是指示nginx处理来自二级域名example.com下的全部请求
server_name     *.example.com;
server_name     .example.com;
复制代码
  1. 处理全部以example开头的域名下的请求
server_name     example.*;
复制代码

Nginx还容许server_name的值是自定义的、无效的域名,它只管根据HTTP请求头中的域名来响应请求,不会去关注该域名是不是有效的。

这种特性在局域网中是很是有用的,或者是你已经知道全部的可能发起请求的客户端。好比,前端经常使用的,在hosts文件中配置的ip-域名对,nginx均可以监听、处理。

Location路由配置块

Location配置的是,Nginx如何响应请求的资源。该指令把请求抽象为特定的文件或文件夹,就像server_name指令指示Nginx如何处理代理域名下的请求同样, 好比http://example.com/blog/, 下面是一些例子:

location / { }
location /images/ { }
location /blog/ { } 
location /planet/ { }
location /planet/blog/ { } 
复制代码

上述是路由字符串匹配,匹配的目标是,http请求中域名以后的全部路径:

请求: Http://example.com/

响应: 假设已经配置了主机 server_name example.com, location /该指令将决定该请求的响应是什么。

Nginx老是会用最精确的路由匹配来处理请求:

请求: 例若有这两个请求http://example.com/planet/blog/ & http://example.com/planet/blog/about/

响应: 在上面的路由匹配中,最终会使用location /planet/blog/ { }路由下的配置处理,即便location /planet/ { }该路由也是匹配的,可是由于前者是更精确的,因此会使用前者而不是后者。

location ~ IndexPage\.php$ { }
location ~ ^/BlogPlanet(/|/index\.php)$ { }
复制代码

location指令后面紧跟着一个波浪号, 表示该路由匹配是正则匹配,而且是区分大小写的。 所以IndexPage.php是可以符合上述的第一个例子的,可是indexpage.php是不行的。在第二个例子中,正则表达式^/BlogPlanet(/|index\.php)$会匹配,诸如/BlogPlanet//BlogPlanet/index.php这样的请求,可是不会匹配到/BlogPlanet, /blogplanet/或者 /blogplanet/index.php这样的请求,由于大小写不符合。

Nginx的正则匹配规则是遵循PCRE(Perl Compatible Regular Expression)的。

location ~* \.(pl|cgi|perl|prl)$ { }
location ~* \.(md|mdwn|txt|mkdn)$ { }
复制代码

若是你想使匹配规则对大小写不敏感,那么在~后面添加一个*. 上述的例子是指定nginx如何处理以文件扩展名结尾的请求。 在第一个例子中,全部以.pl, .PL, .cgi, .CGI, .perl, .Perl, .prl, 和.PrL结尾的文件请求,都是知足匹配规则的.

location ^~ /images/IndexPage/ { }
location ^~ /blog/BlogPlanet/ { }
复制代码

location指令后面跟着 ^~组合,意味着,若是匹配到特定的字符串,就直接中止寻找更精确的路由匹配项,直接使用当前的路由配置。除此以外,与字符串匹配规则同样。若是一个请求符合该指令,那么不论后面是否有更精确的匹配项,直接使用此处的配置规则。关于匹配的顺序以及优先级,后文会有更详细的介绍。

location = / { }
复制代码

最后,若是你在location后面添加了一个等号=, 意味着这是一个精准的匹配,请求路径必须严格等于路由项,才会中止匹配查询。举个栗子:最后的例子会匹配到http://example.com/, 而不会匹配http://example.com/index.html, 使用精准匹配能够轻微的提高响应速度,在某个请求须要频繁的被调用的场景下是很是有用的。

该指令的处理顺序以下:

  1. 精准匹配路由是最早被处理的,若是发现符合条件的,Nginx会中止匹配搜索,直接处理请求
  2. 字符串匹配是第二优先处理的,若是遇到^~匹配项,nginx会中止匹配,直接处理。不然,会持续匹配搜索直到找到最合适的匹配项
  3. 正则匹配项(~~*)是第三优先处理的,若是遇到符合条件的,中止搜索,处理请求
  4. 若是前三步都没有匹配到,那么将会使用最通配的字符串匹配

确保代理域名下的每一个文件、文件夹至少可以匹配一个location指令

注意:
不建议也不支持嵌套的location配置块

路由的根路径和入口文件

location也是一个块指令,里面能够配置相关的指令

一旦Nginx匹配到了一个请求的最佳匹配路由,该请求的响应就会被相关location内的指令处理。例如:

location / {
    root html;
    index index.html index.htm;
}
复制代码

本例中,文件的根路径会被定位在html/目录下,在默认的nginx配置文件中,例子中的完整文件路径是/etc/nginx/html/

请求: http://example.com/blog/includes/style.css

响应: nginx会尝试在/etc/nginx/html/blog/includes/style.css路径下寻找目标文件

注意:
若是须要的话,root的值也可使用绝对路径

index指令是告诉nginx,若是没有在目标路径找到目标文件,那么使用index指令的值表明的文件做为返回值。 例如:

请求: http://example.com

响应: nginx没有找到合适的匹配项,就会返回/etc/nginx/html/index.html文件

若是index指令的值有多个,nginx会按顺序寻找文件,直到发现第一个存在的,以此做为响应。若是在相关的文件夹下index.html不存在,会寻找index.htm, 若是依然不存在,就会返回404.

下面是一个稍微复杂的例子,展现了一个代理example.com域名的服务上的一系列location配置

location / {
    root   /srv/www/example.com/public_html;
    index  index.html index.htm;
}

location ~ \.pl$ {
    gzip off;
    include /etc/nginx/fastcgi_params;
    fastcgi_pass unix:/var/run/fcgiwrap.socket;
    fastcgi_index index.pl;
    fastcgi_param SCRIPT_FILENAME /srv/www/example.com/public_html$fastcgi_script_name;
}
复制代码

在这个例子中,全部获取以.pl为扩展名的资源的请求,都会被第二个location块处理, 在该指令块里定义了一个fastcgi回调来处理全部的请求。其余的请求则是由第一个指令块处理。 资源的请求被分发在文件系统中的/srv/www/example.com/public_html/路径下,若是请求的目标文件不存在,nginx会寻找index.htmlindex.htm代替,若是这两个文件也不存在,就会返回404.

咱们来分析一下下面的几个例子:

请求: http://example.com

响应: 该请求会被第一个location匹配

  1. /srv/www/example.com/public_html/index.html 路径下的文件,有的话直接返回,没有走第二步
  2. /srv/www/example.com/public_html/index.htm路径下的文件,有的话返回,没有的话走第三步
  3. 返回404错误

请求: http://example.com/blog/
响应: 该请求会被第一个location匹配,请求路径里面有指出资源路径,所以拼接root路径

  1. /srv/www/example.com/public_html/blog/index.html 路径下的文件,有的话直接返回,没有走第二步
  2. /srv/www/example.com/public_html/blog/index.htm路径下的文件,有的话返回,没有的话走第三步
  3. 返回404错误

请求: http://example.com/tasks.pl
响应: 请求的资源是以.pl结尾的,会被第二个location匹配,资源名称是tasks.pl,拼接上root路径 nginx会寻找/srv/www/example.com/public_html/tasks.pl 路径下的文件,而后用指定的FASTCGI回调处理该文件,而后把结果做为响应返回

请求: http://example.com/username/roster.pl
响应: 请求的资源是以.pl结尾的,会被第二个location匹配,资源名称是roster.pl,路径是username, 拼接上root路径 nginx会寻找/srv/www/example.com/public_html/username/roster.pl 路径下的文件,而后用指定的FASTCGI回调处理该文件,而后把结果做为响应返回

总结(译者)

  • nginx location 指令是取请求uri,与location指令后面紧跟的字符串正则表达式作比较,选择匹配度最高的location块,用其中定义的指令处理请求。
  • root指令调整了资源的寻址路径,nginx会按照root + uri的路径来寻找请求资源
  • 若是uri没有明确指定资源名(具体的文件名),那么nginx会读取index指令的值做为默认返回值, 若是没有的话返回404

好文推荐

快狗打车前端团队博文前端想要了解的Nginx

相关文章
相关标签/搜索