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中定义,那么break
和last
基本一样
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/.*
如果rewrite
在location
中定义,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
指令可以在server
和location
中定义
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;
}