nginx基础配置指南 - 配置文件语法

  (2012-01-08 13:08:08)
转载
标签: 

nginx

 

基础

 

配置

 

指南

分类: Web应用
  1. 这是本人的读书笔记,自己翻译了一下,水平有限,不求太准确,只求自己回头能看懂,各位看官见谅。

    原文地址:  http://library.linode.com/web-servers/nginx/configuration/basic

     

     

    一、全局配置

     

    我们从nginx的默认配置文件开始学习如何配置nginx

     

    文件: nginx.conf

     

    #user  nobody;
    worker_processes  1;

    #error_log  logs/error.log;
    #error_log  logs/error.log  notice;
    #error_log  logs/error.log  info;

    #pid        logs/nginx.pid;

    events {
        worker_connections  1024;
    }

     

    上边这部分是nginx.conf的前几行,一般情况下不需要修改这些选项。在此处有几个方面需要我们注意:

     

  2. 所有以"#"开头的行,都是注释行,nginx不会对其进行处理。
  3. 指令以一个变量名为开头,后边跟着一个参数(例如 1 或 logs/nginx.pid)或者一系列参数("logs/error.log notice")
  4. 所有指令都以分号";"结尾。
  5. 一些指令,例如上边的events,可以包含多个子指令作为参数。这些子指令被大括号{ }封闭。
  6. 空白字符(tab,空格,换行符)会被忽略,nginx不会对其进行处理。可以使用空白字符增强配置文件的可读性。
  7.  

    我们继续向下查看nginx.conf

     

    http {
        include       mime.types;
        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  logs/access.log  main;

        sendfile        on;
        #tcp_nopush     on;

        #keepalive_timeout  0;
        keepalive_timeout  65;

     

          #gzip  on;

     

    http {  } 块中的配置一般来说也不需要进行修改。我们着重关注以下几点:

     

  8. 开头的 include 声明将mime.types文件包含进了nginx.conf中,mime.types文件存放在/opt/nginx/conf/mime.types。虽然使用include声明可以使配置文件显得更有组织和清晰,但是太多的递归include会造成混乱,所以要有节制的使用include
  9. 可以将log_format前边的"#"去掉,修改后边的参数,获得自己希望的日志格式
  10. gzip指令告诉服务器使用"on-the-fly"gzip压缩,以减少传输中所用的带宽。这个指令与Apache的mod_deflate功能一样。
  11. 如果要激活gzip压缩功能,可以在配置文件中加入如下指令。

     

            gzip on;
            gzip_http_version 1.1;
            gzip_comp_level 2;
            gzip_types    text/plain text/html text/css
                          application/x-javascript text/xml
                          application/xml application/xml+rss
                          text/javascript;

    使用gzip压缩虽然可以减少一部分带宽消耗,但同时也会增加服务器的CPU消耗。gzip_comp_level的取值可以从19,设置为9则消耗最多CPU,设为1消耗最少,默认值是1

     

    二、server配置

     

    我们接着向下继续查看nginx.conf,请注意,上边的http {  } 到此处才完全封闭,也就是说server的配置也包含在http { }中。

     

            server {
                    listen       80;
                    server_name  localhost;

                    access_log  logs/localhost.access.log  main;

                    location / {
                        root   html;
                        index  index.html index.htm;
                    }
            }
    }

     

    Server指令段是大多数用户配置他们服务器的地方。在Server指令段中有不少重要指令。listen指令告诉nginx在一个特定的主机名或IPTCP端口上监听连接。默认情况下,HTTP服务使用端口80。以下的listen指令都是合法的:

     

    listen     127.0.0.1:80;
    listen     localhost:80;

    listen     127.0.0.1:8080;
    listen     localhost:8080;

    listen     192.168.3.105:80;
    listen     192.168.3.105:8080;

    listen     80;
    listen     *:80;
    listen     8080;
    listen     *:8080;

    listen     12.34.56.77:80;
    listen     12.34.56.78:80;
    listen     12.34.56.79:80;

     

    上边的例子中列举了一些不同的使用惯例:

     

  12. 头两个指令指明服务器应该监听在127.0.0.1或者本地的loopback接口上。localhost127.0.0.1的主机名,在/etc/hosts定义。
  13. 第二对指令和第一对的例子一样,就是端口变成了8080
  14. 第三对指令指明服务器同时在192.168.3.105的地址上监听80,8080两个端口
  15. 第四组指令包含4个指令,指明在所有接口上监听指定端口。listen 80 listen *:80是一模一样的作用。
  16. 最后一组指令指明服务器在3个不同IP上都监听80端口。
  17.  

    server_name指令允许管理员提供"基于主机名的虚拟主机",也就是服务器监听在一个单一IP地址上,但是却可以根据HTTP请求中的header不同而访问不同的域名。请看下边这些示例:

     

    server_name   ducklington.org;
    server_name   ducklington.org www.ducklington.org;
    server_name   *.ducklington.org;
    server_name   .ducklington.org;

    server_name   ducklington.*;

    server_name   ducklington.org bucknell.net brackley.org;
    server_name   localhost litchfield bleddington;

    server_name   "";

     

    独立的server_name使用空白符分隔。nginx允许管理员给服务器配置多个名字,所以一个服务器可以服务多个不同名称的请求。也可以使用通配符"*"和正则表达式来指明虚拟主机名字。我们来分析一下上边示例:

     

    第一组示例,第一行我们指定了server_name为ducklington.org,所以所有访问http://ducklington.org的请求会被这台服务器捕捉到。在第二行中所有访问ducklington.org和www.ducklington.org都会被这台服务器捕捉。

    第三行和第四行的作用是相同的,*.ducklington.org和.ducklington.org表达的意思相同,所有基于ducklington.org的二级域名都会被捕捉。(www.ducklington.org,mirrors.ducklington.org等等)

     

    第二组示例,所有以ducklington.开头的域名都会被捕捉,例如ducklington.com, ducklington.net, ducklington.org, ducklington.morris.com, ducklington.dance.org,ducklington.morris.dance.com等等。

     

    第三组示例,所有发往指令中的3个域名的请求都会被捕捉。多个域名可以安全的合并在一个指令中。另外,nginx允许给虚拟主机指定不合法的域名,比如例子中的localhost, litchfiled,和 bleddington。nginx只在HTTP header中搜索指定的名称,而不关心这个名称是否是合法的域名。在这组示例中,主机名可以写在/etc/hosts文件中。

     

    当你的nginx部署在局域网中或者你可以明确知道访问这台主机的用户的时候,使用非合法域名的主机名非常有用。This includes front-end proxy servers that have entries for the IP address that nginx is listening on in their /etc/hosts file.

     

    最后一组示例," "空白引号告诉nginx捕捉那些请求中不包含主机名或包含没有指定的主机名的请求。

     

    我们继续向下看server指令段,access_log指令。

     

    access_log logs/ducklington.access.log;
    access_log /srv/http/ducklington.org/logs/access.log;
    access_log /var/log/nginx/access/ducklington.org;
    access_log off;

     

    第一行的log文件位置是相对路径,存储在/opt/nginx/logs/ducklington.access.log

    第二、三的log文件位置是绝对路径。

    如果不需要access_log,可以将它关闭,不过通常不建议关闭。

     

    server指令段中的最后一个指令是 location

    就像可以使用server_name指令允许nginx根据请求中的信息来相应处理客户发送来的请求一样,location指令允许管理员定义响应不同请求的资源该去什么地方寻找。

     

    location / { }
    location /images/ { }
    location /blog/ { }
    location /planet/ { }
    location /planet/blog/ { }

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

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

    location ^~ /images/IndexPage/ { }
    location ^~ /blog/BlogPlanet/ { }

    location = / { }

     

    第一组的5行例子,是逐字匹配。匹配请求的主机名以后的部分。假定有一个请求http://ducklington.org/ ,假设server_name配置为ducklington.org,那么"location /"指令会捕捉这个请求。nginx总是使用最精确的匹配来处理请求。例如,一个http://ducklington.org/planet/blog/ 的请求和一个 http://ducklington.org/planet/blog/about/ 的请求,会被"location /planet/blog/" 指令捕捉到,尽管"location /planet/" 也能匹配这2个请求。

     

    当一个location 指令后边跟着一个"~"波浪线符号时,nginx会执行一个正则表达式匹配。这些匹配总是大小写敏感的。所以在第二组,第一行的示例中,包含IndexPage.php的请求会被捕捉,而包含indexpage.php的请求则不会。在第二行的示例中,所有包含/BlogPlanet/ 和/BlogPlanet/index.php的请求会被捕捉,而包含/BlogPlanet, /blogplanet/, /blogplanet/index.php的请求则不会。nginx使用Perl Compatible Regular Expressions (PCRE)正则。

     

    location指令后便跟着一个"~*"波浪线和星号时,nginx只能给一个正则表达式匹配,但是会忽略大小写。在第三组第一行的示例中,所有后缀为.pl, .PL, .cgi, .CGI, .perl, .Perl, .prl, .PrL的请求都会被捕捉。

     

    第四组示例中的location 指令功能和第一组的相同,所不同的是,当location后边跟着"^~"的时候,它强制nginx停止搜索更多的匹配。在第四组的示例中,"^~ /images/IndexPage/" 和 "^~ /blog/BlogPlanet/"会强制nginx捕捉包含有对应表达式的请求,即便还有其他location指令也可以匹配这个请求。

     

    最后一组示例,"="等号会精确匹配请求的路径,并且使nginx停止搜索其他更详尽的匹配。例如,http://ducklington.org/ 会被捕捉到,但是 http://ducklington.org/index.html 则不会被捕捉。使用精确匹配可以轻微加速请求,尤其是在某些请求特别受欢迎的时候。

     

    location指令的执行顺序如下:

     

    精确匹配会第一个被处理。如果发现精确匹配,nginx停止搜索其他匹配。

    接下来处理逐字匹配指令,如果使用了"^~",则nginx停止搜索其他匹配,否则nginx会继续处理其他location指令。

    接下来处理带有"~""~*"的指令,如果找到相应的匹配,则nginx停止搜索其他匹配。

    当没有正则表达式或者没有正则表达式被匹配的情况下,那么匹配程度最高的逐字匹配指令会被使用。

     

     

    三、Location 配置

     

    一旦nginx为一个给定的请求选择了一个location,那么如何回应这个请求,则是由location指令块中的内容决定的。一个基本的location配置块如下:

     

    location / {
        root   html;
        index  index.html index.htm;
    }

     

    在上边这个例子中,web文档根目录被指定为 html/ 目录,加上nginx的默认安装目录,则绝对路径应该为/opt/nginx/html/。假如有一个针对/blog/includes/style.css的请求,而nginx.conf中没有location指令匹配这个请求,则nginx会去查找/opt/nginx/html/blog/includes/style.css这个文件。如果你喜欢,也可以在root中使用绝对路径。

     

    index指令告诉nginx如果一个请求中不包含文件名,那么文件系统上的哪个文件应该默认被使用。比如请求http://.ducklington.org/ 那么真正访问的资源是/opt/nginx/http/index.html。如果index指令后边有多个文件,则nginx会按照列表的顺序查找,用找到的第一个文件回应。假如index.html找不到,则查找index.htm,如果都找不到,则返回404错误。

     

    让我们来看一个更复杂的例子:

     

    location / {
        root   /srv/www/ducklington.org/public_html;
        index  index.html index.htm;
    }

    location ~ \.pl$ {
        gzip off;
        include /etc/nginx/fastcgi_params;
        fastcgi_pass  127.0.0.1:8999;
        fastcgi_index index.pl;
        fastcgi_param  SCRIPT_FILENAME  /srv/www/ducklington.org/public_html$fastcgi_script_name;
    }

     

    在这个例子中,所有结尾带有.pl的请求都会被第二个location指令块处理,在其指令块中指定了fastcgi处理这些请求。如果请求中不包含.pl,则第一个location指令块负责处理,会在/srv/www/ducklington.org/public_html/目录下寻找请求的文件。如果请求中没有指定文件名,则nginx会去寻找index.html和index.htm。如果找不到index指令中定义的2个文件,则返回404错误。

     

  18. 请求http://ducklington.org/,如果/srv/www/ducklington.org/public_html/index.html存在,则返回此文件。如果不存在,则查找/srv/www/ducklington.org/public_html/index.htm,如果也不存在,则返回404错误。
  19. 请求http://ducklington.org/blog/,如果/srv/www/ducklington.org/public_html/blog/index.html存在,则返回此文件。如果不存在,则查找/srv/www/ducklington.org/public_html/blog/index.htm,如果也不存在,则返回404错误。
  20. 请求http://ducklington.org/tasks.pl,会使用FastCGI处理器执行/srv/www/ducklington.org/public_html/tasks.pl,然后返回处理结果。
  21. 请求http://ducklington.org/squire/roster.pl,会使用FastCGI处理器执行 /srv/www/ducklington.org/public_html/squire/roster.pl,然后返回处理结果。
  22.  

    四、最佳指南

     

    学习了上边的例子,已经让我们有足够的信心去开始尝试编写自己的nignx.conf文件了。以下是一些给管理员的最佳指南。

     

    第一、压缩server指令段的配置,使用include声明来保持配置文件的整洁。

     

    例如对于ducklington.org这个服务器,俄哦们把它的server指令段配置文件存储在/srv/www/ducklington.org/nginx.conf,然或在主配置文件/opt/nginx/conf/nginx.conf中使用include指令。

     

    文件/opt/nginx/conf/nginx.conf:

     

    http {
          # [...]

          include /srv/www/ducklington.org/nginx.conf;

          # [...]
    }

     

    在本例中,服务器ducklington.org的root目录在/srv/www/ducklington.org/public_html/,如果我们希望将所有nginx相关的文件都放在/opt/nginx/目录下,那么我们可以在/opt/nginx/conf/ducklington.conf中指定root为/opt/nginx/http/ducklington.org/,然后再在http { } 指令段包含这个配置文件。

     

    http {
          # [...]

          include ducklington.conf;

          # [...]
    }

     

    我们通常建议管理员坚定地保持一个一致的文件命名规范,保持文件的有序和良好的格式可以极大的减少维护nginx服务器的负担。


  23. 五、access log的分割

     


  24. Igor Sysoev(Nginx作者)建议的方法是写如下一个hourly cron执行。


  25. log_dir="/var/log/nginx"
    date_dir=`date +%Y/%m/%d/%H`
    /bin/mkdir -p ${log_dir}/${date_dir} > /dev/null 2>&1
    /bin/mv ${log_dir}/access.log ${log_dir}/${date_dir}/access.log
    /bin/mv ${log_dir}/error.log ${log_dir}/${date_dir}/error.log
    kill -USR1 `cat /var/run/nginx.pid`
    /bin/gzip ${log_dir}/${date_dir}/access.log &
    /bin/gzip ${log_dir}/${date_dir}/error.log &

  26.  

  27. 另外一种方法是使用logrotate,参考 http://drumcoder.co.uk/blog/2012/feb/03/nginx-and-logrotate/

  1. [root@demo ~]#  vi /etc/logrotate.d/nginx

    修改里面配置如下:

    /var/log/nginx/*.log {
        daily
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 640 root adm
        sharedscripts
        postrotate
                [ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.pid`
        endscript
    }


  2. 一些选项的说明:
      daily - 每天做一次日志轮转
      missingok - 如果找不到日志可轮转也不报错
      rotate 52 - 轮转52次,然后删掉最旧的
      mail [email protected] - 删掉旧日志前,将旧日志发送到这个邮箱
      compress - 使用gzip压缩旧日志
      delaycompress - 留下一个轮转过的日志不进行压缩,以便进程在需要的时候可以继续向其中写入信息
      notifempty - 空文件无需轮转
      sharedscripts - 当通知nginx日志已经轮转完毕的时候,只执行一次postrotate脚本,而不是每个文件轮转后都执行

     

你可能感兴趣的:(linux)