nginx 相关知识点

安装

在mac系统中使用brew命令安装, 如果要支持ehco指令,请安装echo-modul模块

 brew update
 # 安装普通版
 brew install nginx

 # 安装支持echo指令的nginx, 建议安装此版本,可以方便调试
 brew install nginx-full --with-echo-module

开机启动,重启,关闭等常用操作

通过brew install nginx安装,支持如下操作

 # 设置开机启动
 brew services start nginx
 # 常用操作
 brew services stop | reload | restart nginx
 # 查找是否成功启动
 ps -aux | grep nginx
 # 验证配置是否正确,建议修改配置之后执行此命令验证
 nginx -t
 # 设置nginx的前缀path路径,在nginx配置文件中,像access_log error_log需要指定前缀文件路径
 # 默认前缀路径是nginx的安装路径
 nginx -p prefix_file_path
 # 指定nginx运行配置文件
 nginx -c nginx_conf_path
 # 查看nginx支持的命令
 nginx -h

通过 brew install nginx-full --with-echo-module 安装, 支持如下操作

  启动
  nginx
  停止 重启
  nginx -s stop | reload

nginx 内置常量

location ~ .*args$ {
  echo $document_root;
  echo $document_uri;
  echo $fastcgi_script_name;
  echo $request_uri;
  echo $request_method;
  echo $args;
  echo $remote_addr;
  echo $remote_port;
  echo $server_addr;
  echo $server_port;
  echo $server_name;
  echo $content_type;
  echo $content_length;
  echo $scheme;
}

请求:http://localhost:8080/test/args?a=1&b=2
输出:
/usr/local/Cellar/nginx-full/1.12.2/html
/test/args
/test/args
/test/args?a=1&b=2
GET
a=1&b=2
127.0.0.1
62787
127.0.0.1
8080
localhost
(为空)
(为空)
http

需要注意:

  • $document_root可以使用root或alias指令配置,或在nginx启动的时候使用-p指定

  • $request_uri/开头

  • 内置常量会传递给fastcgi或者cgi程序

常用模块

ngx_http_rewrite_module

此模块提供常用指令有:rewrite, last, break, redirect, permanent, set, if

使用rewrite指令有两个目的:

1 通过正则匹配到的uri并改写uri, 从而满足php框架使用uri做路由分发

2 实现特定的uri使用location去处理,从而满足不同的uri有不同的location处理,例如静态文件,php文件等有不同的location处理

理解这两个目的很重要!

rewrite指令可以使用在server上下文中,也可以使用在location上下文中`

server {
    # $1表示第一个括号匹配的内容
    rewrite ^/(.*)$ /msie/$1;

    location ~ /msie/.* {
        rewrite_log on;
        echo "rewrite";
        echo $request_uri;
        echo $document_uri;
    }
}

# 当请求http://localhost:8080/test?a=1&b=2 输出:
rewrite
/test?a=1&b=2  # 并不是/msie/test?a=1&b=2
/msie/test  # 改写后的url

输出结果说明: 1 rewrite顺利匹配到url并路由到location ~ /msie/.* 处理本次请求 2 rewrite没有改变$request_uri, 以$request_uri做路由的请特别注意 3 $document_uri变量已经改变为rewrite之后的/msie/test

rewrite regexp 常用表达式

# 以/author开头的url 重写到/show/author
rewrite ^/author/(.*)$ /show/author?id=$1;

# 以/library开头的url 或者/library/ 或者/library/xxx?a=1 重写到/show/library/$1
rewrite ^/library(?:/([^\?]*))?$ /show/library/$1;

当输入/library/test/?a=1, 正则开始匹配:
^首先匹配开头,成功
/library匹配到源uri中/library位置
然后(?:/([^\?]*))? 开始匹配,首先(?:expression)是一个顺序环视[只匹配字符串,不占有字符]
顺序环视中/开始匹配源字符串中/library后面的一个/,匹配成功,然后[^\?]开始匹配,开始匹配t,匹配成功,由于[^\?]*是贪婪模式,继续匹配直到/library/test/?的?失败,所以[^\?]*匹配的内容包括?, 如题[^\?]* 匹配到的就是test 所以 $1=test

break指令

break指令会终止ngx_http_rewrite_module模块中所有指令的执行

和break类似的指令是last, 如果rewrite在server中定义,那么breaklast基本一样

server {
    # 执行到break指令后,nginx将根据被重写的uri
    # 重新发起location匹配阶段,最终会匹配到location ~ /msie/.*
    rewrite ^/(.*)$ /msie/$1 break; # 这里把break改成last也一样

    location ~ /msie/.* {
        echo "rewrite";
    }
}

# 输入url: localhost/test?a=1
# 输出: "rewrite"
# 证明匹配到了location ~ /msie/.*

如果rewritelocation中定义,nginx不会重新发起location匹配,直接使用本次location的内容输出

server {
    location /1 {
       echo "1";
       rewrite   (.*)   /2?o_uri=$1 break;
    }

    location /2 {
       echo "2";
    }
}

# 输入url: localhost/1?a=1
# 输出: "1" 证明匹配到了location /1 证明location匹配终止在 location /1中 并没有到location /2中

这个实例中,rewrite指令加入break指令,目的只是为了重写uri

last指令

last 指令是用于为被rewrite后的uri重新匹配新的location

server {
    location /1 {
       echo "1";
       rewrite   (.*)   /2?o_uri=$1 last;
    }

    location /2 {
       echo "2";
    }
}

# 输入url: localhost/1?a=1
# 输出: "2" 证明匹配到了location /2 证明location匹配终止在 location /2中
# 这里为什么只输出了2没有输出1呢,因为nginx执行有多个阶段,echo指令是在rewrite之后执行,由于
# rewrite uri后最终匹配到了location /2, 所以执行location /2中的echo指令

redirect, permanent 指令

使用这个指令的目的就是重定向到一个新的url里面,比如网站里面某一个url过期了,当用户访问这个url,可以重定向到首页, 本次请求返回给客户端的状态码是302 表示永久转移,如果想临时转移则使用permanent指令 返回状态码301

# 实现无效的url的重定向 返回302
rewrite /invalid_url/.* $scheme://$server_name redirect;
# 返回301
rewrite /invalid_url/.* $scheme://$server_name permanent;

if 指令

可以通过if指令实现对$scheme, $http_host, $http_user_agent $server_name等变量判断, if 指令可以在serverlocation中定义

if ($scheme = "http") {
  rewrite ^ https://www.thegeekstuff.com$uri permanent;
}

if ($http_host = thegeekstuff.com) {
  rewrite  (.*)  https://www.thegeekstuff.com$1;
}

if ($http_user_agent = MSIE) {
    rewrite ^(.*)$ /pdf/$1 break;
}

set 指令 可以给变量赋值

 location ~* ^/(a)\.(jpg) {
    set $img_name $1;
    set $img_ext $2;
    # 发送给php程序处理
    rewrite (.*)  /index.php/?img_name=$img_name&img_ext=$img_ext;
}

location

location匹配内容

location匹配的时候,被匹配的是uri, 不包括协议和域名,也不包括?后面的内容

输入url: www.test.com/path/info/test?a=1&b=2
匹配内容:/path/info/test

使用正则

如果要使用正则表达式,则必须使用“~”,“~*”修饰才可以,这和rewrite不一样

"~" : 区分大小写
"~*": 不区分大小写
 =: 精确匹配
 ^~: 只匹配以 uri 开头

最长匹配规则

location / {    
    [ configuration A ]
} 
location /documents/ {
    [ configuration B ]
}

输入 /documents/ 匹配到B

正则匹配成功

不需要完全匹配到uri, 正则表达式匹配成功即可

locaction ~ (^/path\/info) {
    [configurationC]
}

输入URL: /path/info/test 可以匹配到locaction ~ (^/path\/info)

ngx_http_proxy_module

此模块实现http代理, 简单配置如下

location / {
    proxy_pass  http://localhost:8000;
    proxy_set_header Host  $host;
    proxy_set_header X-Real-IP $remote_addr;
}

results matching ""

    No results matching ""