1.nginx中location匹配规则
1.1优先级顺序
- 1.= : 表示精确匹配后面的url
- 2.~ : 表示正则匹配,但是区分大小写
- 3.~* : 正则匹配,不区分大小写
- 4.^~ : 表示普通字符匹配,如果该选项匹配,只匹配该选项,不匹配别的选项,一般用来匹配目录
- 5.@ : "@" 定义一个命名的 location,使用在内部定向时,例如 error_page
shell
## 排名顺序
location = /uri ## =开头表示精确匹配,只有完全匹配上才能生效。
location ^~ /uri ## ^~ 开头对URL路径进行前缀匹配,并且在正则之前。
location ~ pattern ##~开头表示区分大小写的正则匹配。
location ~* pattern ##~*开头表示不区分大小写的正则匹配。
location /uri ##不带任何修饰符,也表示前缀匹配,但是在正则匹配之后。
location / ##通用匹配,任何未匹配到其它location的请求都会匹配到,相当于switch中的default。
shell
location = / {
#规则A
}
location = /login {
#规则B
}
//匹配目录
location ^~ /static/ {
#规则C
}
## 区分大小写
location ~ \.(gif|jpg|png|js|css)$ {
#规则D
}
## 不区分大小写
location ~* \.png$ {
#规则E
}
location / {
#规则F
}
那么会产生如下效果
- 访问根目录
/,
比如http://localhost/
将匹配规则 A - 访问
http://localhost/login
将匹配规则B,http://localhost/register
则匹配规则 F - 访问
http://localhost/static/a.html
将匹配规则 C - 访问
http://localhost/a.gif
,http://localhost/b.jpg
将匹配规则 D 和规则 E,但是规则 D 顺序优先,规则 E 不起作用,而http://- - - localhost/static/c.png
则优先匹配到规则 C - 访问
http://localhost/a.PNG
则匹配规则 E,而不会匹配规则 D,因为规则 E 不区分大小写。
shell
# 直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。
# 这里是直接转发给后端应用服务器了,也可以是一个静态首页
# 第一个必选规则
location = / {
proxy_pass http://tomcat:8080/index
}
# 第二个必选规则是处理静态文件请求,这是 nginx 作为 http 服务器的强项
# 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
root /webroot/res/;
}
# 第三个规则就是通用规则,用来转发动态请求到后端应用服务器
# 非静态文件请求就默认是动态请求,自己根据实际把握
# 毕竟目前的一些框架的流行,带.php、.jsp后缀的情况很少了
location / {
proxy_pass http://tomcat:8080/
}
1.2rewrite写法相关
- last – 基本上都用这个 Flag
- break – 中止 Rewirte,不再继续匹配
- redirect – 返回临时重定向的 HTTP 状态 302
- permanent – 返回永久重定向的 HTTP 状态 301
1.判断表达式
- -f 和 !-f 用来判断是否存在文件
- -d 和 !-d 用来判断是否存在目录
- -e 和 !-e 用来判断是否存在文件或目录
- -x 和 !-x 用来判断文件是否可执行
2.定义一个全局变量
shell
# 例:http://localhost:88/test1/test2/test.php?k=v
$host:localhost
$server_port:88
$request_uri:/test1/test2/test.php?k=v
$document_uri:/test1/test2/test.php
$document_root:D:\nginx/html
$request_filename:D:\nginx/html/test1/test2/test.php
3.rewrite配置
- last 和 break关键字的区别只用到了break,即匹配到此处后不会继续跳。
- permanent 和 redirect关键字的区别
rewrite … permanent
永久性重定向,请求日志中的状态码为301 rewrite … redirect
临时重定向,请求日志中的状态码为302
shell
server {
listen 80;
server_name demo.com;
rewrite ^(.*)$ https://${server_name}$1 permanent; ##http重定向https
}
1.3 Redirect语法
shell
server {
listen 80;
server_name start.igrow.cn;
index index.html index.php;
root html;
if ($http_host !~ "^star\.igrow\.cn$") {
rewrite ^(.*) http://star.igrow.cn$1 redirect;
}
}
2.nginx里面的变量
1.定义变量
shell
server {
listen 80;
server_name localhost;
location /test {
set $foo hello;
set $first "hello";
echo "foo: $foo,first: ${first}";
}
}
2.变量的作用域
shell
##注意,只要定义了变量,就会在整个serve中起作用
server {
listen 8080;
location /foo {
echo "foo = [$foo]";
}
location /bar {
set $foo 32;
echo "foo = [$foo]";
}
}
# [root@localhost html]# curl 'http://localhost/foo'
# foo = []
# [root@localhost html]# curl 'http://localhost/bar'
# foo = [32]
# [root@localhost html]# curl 'http://localhost/foo'
# foo = []
shell
## 在serve的内部跳转中依然存在这个变量
server {
listen 8080;
location /foo {
set $a hello;
echo_exec /bar;
}
location /bar {
echo "a = [$a]";
}
}
3.内建变量
$uri
和$request_uri
由 ngx_http_core
模块提供的内建变量 $uri
,可以用来获取当前请求的 URI
(经过解码,并且不含请求参数), 而 $request_uri
则用来获取请求最原始的 URI
(未经解码,并且包含请求参数)。简单来说,$uri
不带参数只获取路由,$request_uri
带参数
shell
location /test-uri {
echo "uri = $uri";
echo "request_uri = $request_uri";
}
#[root@localhost html]# nginx -s reload
#[root@localhost html]# curl localhost/test-uri
#uri = /test-uri
#request_uri = /test-uri
#[root@localhost html]# curl "localhost/test-uri?a=3&b=4"
#uri = /test-uri
#request_uri = /test-uri?a=3&b=4
#[root@localhost html]# curl "localhost/test-uri/hello%20world?a=3&b=4"
#uri = /test-uri/hello world
#request_uri = /test-uri/hello%20world?a=3&b=4
- $arg_XXX
另一个特别常用的内建变量其实并不是单独一个变量,而是有无限多变种的一群变量,即名字以 arg_
开头的所有变量,我们估且称之为 $arg_XXX
变量群。 一个例子是 $arg_name
,这个变量的值是当前请求中名为 name 的参数的值,而且还是未解码的原始形式的值。简单来说,就是获取?后面的参数名字
shell
location /test-arg {
echo "name: $arg_name";
echo "class: $arg_class";
}
# [root@localhost html]# nginx -s reload
# [root@localhost html]# curl localhost/test-arg
# name:
# class:
# [root@localhost html]# curl "localhost/test-arg?name=Tom&class=3"
# name: Tom
# class: 3
# [root@localhost html]# curl "localhost/test-arg?name=hello%20world&class=9"
# name: hello%20world
# class: 9
- 全局变量
shell
arg_PARAMETER #这个变量包含GET请求中,如果有变量PARAMETER时的值。
args #这个变量等于请求行中(GET请求)的参数,如:foo=123&bar=blahblah;
binary_remote_addr #二进制的客户地址。
body_bytes_sent #响应时送出的body字节数数量。即使连接中断,这个数据也是精确的。
content_length #请求头中的Content-length字段。
content_type #请求头中的Content-Type字段。
cookie_COOKIE #cookie COOKIE变量的值
document_root #当前请求在root指令中指定的值。
document_uri #与uri相同。
host #请求主机头字段,否则为服务器名称。
hostname #Set to themachine’s hostname as returned by gethostname
http_HEADER
is_args #如果有args参数,这个变量等于”?”,否则等于”",空值。
http_user_agent #客户端agent信息
http_cookie #客户端cookie信息
limit_rate #这个变量可以限制连接速率。
query_string #与args相同。
request_body_file #客户端请求主体信息的临时文件名。
request_method #客户端请求的动作,通常为GET或POST。
remote_addr #客户端的IP地址。
remote_port #客户端的端口。
remote_user #已经经过Auth Basic Module验证的用户名。
request_completion #如果请求结束,设置为OK. 当请求未结束或如果该请求不是请求链串的最后一个时,为空(Empty)。
request_method #GET或POST
request_filename #当前请求的文件路径,由root或alias指令与URI请求生成。
request_uri #包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。不能修改。
scheme #HTTP方法(如http,https)。
server_protocol #请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
server_addr #服务器地址,在完成一次系统调用后可以确定这个值。
server_name #服务器名称。
server_port #请求到达服务器的端口号。
3.nginx接口转发配置
配置反向代理, 比如我们访问http://demo.com/api/aaa/bbb
,我们想要代理到http://api.com/api/aaa/bbb
, 只切换了域名,uri
相同。
shell
location /api {
proxy_pass http://api.com;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header your-custome-header "myHeader";
proxy_set_header X-NginX-Proxy true;
}
- 配置反向代理时,移除前缀。比如我们的服务
http://demo.com/users/aaa/bbb
, 我们想要代理到http://users.com/aaa/bbb
,即切换域名的同时,去掉users
前缀。 区别是proxy_pass
结尾的/
.
shell
location ^~/users/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://users.com/;
}
## 或者用rewrite方式
location ^~/users/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
rewrite ^/users/(.*)/$ $1 break; ## 注意这个rewrite是 a+b 重写成 b
proxy_pass http://users.com; ## 注意这里的区别
}
##自己的 http://101.200.218.760/proxy/bing/HPImageArchive.aspx?format=js&idx=0&n=1
##实际的 https://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1
location ^~/proxy/bing/ {
rewrite ^/proxy/bing/(.*)$ /$1 break;
proxy_pass https://cn.bing.com/;
}
4.nginx默认配置文件
nginx.conf
文件采用自己的
shell
user root;
worker_processes 2; ##进程数 通过lscpu获取
worker_rlimit_nofile 65535; ##最大连接数 通过ulimit -n获得
events {
worker_connections 32767; #65535/2得到
accept_mutex on; #每个woker逐渐接受新的连接
accept_mutex_delay 500ms; # accept_mutex_delay对应于worker等待的时间帧,然后它尝试获取互斥锁并开始接受新的连接
multi_accept on; #multi_accept指令使得NGINX worker能够在获得新连接的通知时尽可能多的接受连接
}
http {
# 隐藏Nginx版本信息
server_tokens off;
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
#自定义头部信息
underscores_in_headers on;
#log_format main '$remote_addr - $proxy_add_x_forwarded_for - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
## 自定义日志格式
log_format main '{"TimeISO":"$time_iso8601",'
'"RemoteUser":"$remote_user",'
'"ServerAddr":"$server_addr",'
'"remote_user":"$remote_user",'
'"xff":"$http_x_forwarded_for",'
'"axff":"$proxy_add_x_forwarded_for",'
'"RemoteAddr":"$remote_addr",'
'"RequestMethod":"$request_method",'
'"scheme":"$scheme",'
'"ServerName":"$server_name",'
'"Referer":"$http_referer",'
'"RequestUri":"$request_uri",'
'"RequestUrl":"$request",'
'"Args":"$args",'
'"RequestBody":"$request_body",'
'"Size":$body_bytes_sent,'
'"ConnectionRequests":$connection_requests,'
'"LocalServiceIP":146,'
'"Status": $status,'
'"ResponseTime":$request_time,'
'"UpstreamTime":"$upstream_response_time",'
'"UserAgent":"$http_user_agent",'
'"https":"$https"'
'}';
#fastcgi模块->服务器与web通信默认60s
fastcgi_connect_timeout 1800s; #指定nginx与后端fastcgi server连接超时时间
fastcgi_send_timeout 1800s; #指定nginx向后端传送请求超时时间(指已完成两次握手后向fastcgi传送请求超时时间)
fastcgi_read_timeout 1800s; #指定nginx向后端传送响应超时时间(指已完成两次握手后向fastcgi传送响应超时时间)
# 启用gzip压缩,提高用户访问速度
gzip on;
gzip_min_length 1k;
gzip_buffers 4 32k;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
gzip_disable "MSIE [1-6].";
server_names_hash_bucket_size 128;
client_max_body_size 100m;
client_header_buffer_size 256k;
large_client_header_buffers 4 256k;
#改host访问这台服务器需要配置这个否则会出现502
resolver 8.8.8.8;
#limit_req_zone:请求频率
#$binary_remote_addr:以客户端IP进行限制
#zone=one:10m:创建IP存储区大小为10M,用来存储访问频率
#rate=10r/s:表示客户端的访问评率为每秒10次
limit_req_zone $binary_remote_addr zone=myRateLimit:20m rate=20r/m;
#增加虚拟主机
include vhost/xxx.conf;
}