Nginx Web服务器
2015 年 02 月 15 日
nginx

    通常, Nginx作为Web服务器, 需要配置一系列虚拟服务器来负责处理特定的域名或者IP。 每个虚拟服务器需要定义处理特定URL集的Location实例, 每个Location实例则可以 代理请求, 返回文件, 重写URL(将请求重定向到其他虚拟服务器), 或者返回错误码, 并且你也可以定义错误码对应的页面。

  • 配置文件

  • nginx默认配置文件叫nginx.conf, 在Linux中通常位于 /usr/local/nginx/conf, /etc/nginx/conf, /usr/local/etc/nginx, 在Mac OSX中, 若使用brew安装默认位于 /usr/local/etc/nginx, 该文件使用指令+ 参数进行配置, 类似

    user             nobody;
    error_log        logs/error.log notice;
    worker_processes 1;
            
  • 通常我们会使用include将配置文件分开, 这样便于管理
  • include       mime.types;
    include	      /path/to/*.conf;
            
  • 任何放在外部的指令配置都被认为是main上下文的, 通常子级上下文重用父级上下文的配置, 也可以重写父级上下文的配置, 下面是一段较为完整的配置结构
  • # main上下文
    user nobody;
    
    events {
        # 事件配置
    }
    
    # http上下文
    http {
    
        # HTTP全局配置, 作用于所有虚拟服务器
    
        # 虚拟服务器1
        upstream server1 {
            server localhost:9080;
        }
        server {
            # 虚拟服务器1的配置
            listen       80 ;           #监听信息
            server_name  www.gaara.com; #虚拟服务器名称
    
            location /one {
                # 处理URL为/one的配置
            }
    
            location /two {
                # 处理URL为/two的配置
            }
    
            # 所有请求转发到server1虚拟服务器
            location / {
                proxy_pass              http://server1;
                proxy_set_header        X-Real-IP $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header        Host $http_host;
            }
        }
    
        upstream server2 {
            server localhost:9090;
        }
        server {
            ...
        }
    }
            
  • 当需要生效新的配置时, 你可以重启nginx或者重新加载配置
  • # 重启
    sudo nginx -s stop && sudo nginx
    # 重新加载配置
    sudo nginx -s reload
    # 之前你也可以测试下配置文件是否有错误
    sudo nginx -t -c /path/to/conf
            
  • 配置虚拟服务器

  • nginx配置文件中至少需要配置一个虚拟服务器, 当客户端请求来时, nginx会选择虚拟服务器来处理该请求。 虚拟服务器通过http上下文 中的server指令进行配置
  • http {
        server {
            ...
        }
    }
            
  • 配置监听 listenserver_name
  • server {
        listen      80;                          # 监听信息
        server_name example.org www.example.org; # 虚拟服务器名称, 若请求匹配到多个server, 会再匹配请求头中的"Host"头, 支持全文, 通配符, 正则表达式
    }
            
  • 请求匹配过程
  • 配置Locations

  • Location配置允许我们将不同的请求转发到不同的虚拟服务器, 或者转发到本地文件等
  • location /some/path/ {
        ...
    }
            
  • Location支持前缀字符串正则表达式匹配
  • {uri}: 前缀字符串匹配
    =: 精确匹配
    ^~: 普通字符串匹配, 若该项匹配, 正则表达式不再检查匹配
    ~: 正则表达式匹配(区分大小写)
    ~*: 正则表达式匹配(不区分大小写)

  • Location匹配过程
  • 首先匹配前缀字符串:
       1. 若"="被匹配到, 则停止匹配。
       2. 若"^~"被匹配到, 则正则表达式不会被检查。
       3. 保存最长匹配的前缀字符串。
    然后匹配正则表达式:
       4. 检查第一个匹配的正则表达式
       5. 若没有匹配到正则表达式, 则使用第3步保存的前缀字符串。

  • Location配置允许你将请求解析为 静态文件转发到其他虚拟服务器
  • server {
        location / {
            proxy_pass http://www.example.com;
        }
    
        location /images/ {
            root /data;
        }
    }
            

    proxy_pass: 指令会将请求转发到被代理服务器响应URI上。
    root:指令会将请求到本地文件资源, 如/images/1.jpg --> /data/images/1.jpg, 这常用来转发web前端静态文件JS, CSS等。

  • 变量

  • nginx.conf允许设置变量, 也有很多预定义的变量, 如Core Http, 我们可以通过 set, map, geo指令, 大多数变量都是和当前请求相关的, 如$remote_addr表示客户端IP,$uri表示当前请求URI。
  • 返回指定码

  • 我们可以通过return指令返回指定码
  • location /notfound/url {
        return 404;
    }
    
    location /permanently/moved/url {
        return 301 http://www.example.com/moved/here; # 可以带上第二个参数, 如重定向URL
    }
            
  • 重写URI

  • 一个URI在请求过程可以通过rewrite指令被修改多次。 该指令有2个必须参数和1个可选参数: 第1个参数为检测的请求URI, 第2个参数为替换的URI, 第3个参数标志停止进一步的重写处理。
  • location /users/ {
        rewrite ^/users/(.*)$ /show?user=$1 break;
    }
            
  • rewrite可以在server和location中使用。在同样的server或location中可以包含 多个rewrite指令,并且被依次执行。
  • server {
        rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
        rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra  last;
        return  403;
        ...
    }
            
  • /download/some/media/file被重写为/download/some/mp3/file.mp3, 第二个rewrite和return将被忽略(因为last标志),但nginx会继续处理请求。若未匹配将返回403错误码
  • rewrite具有两种标志
  • last: 停止当前server或location的rewrite操作,但是location匹配依然会继续,因此新的location块中rewrite依然会执行。
    break: 停止当前server或locatioin的rewrite操作,并且停止location匹配, 因此新的location不会再被执行。

  • 配置错误页面

  • 当返回错误码时,我们可以通过error_page指定错误页面。
  • error_page 404 /404.html;
            
  • 我们也可以替换错误码, 如用户访问旧的网页, 我们就可以将其重定向到新页面。
  • location /old/path.html {
        error_page 404 =301 http:/example.com/new/path.html;
    }
            
  • 当然,我们可以不定义error_page,而是由后端服务器来处理。
好人,一生平安。