准备工作
# 先初始化以下测试目录
mkdir -p /root/www/nginx/{abc,bbs}/
# 创建abc目录下得Index文件
vi /root/www/nginx/abc/index.html
# 内容
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>abc</title>
<head>
<body>
<H1>
www.abc.com
</H1>
</body>
</html>
# 创建bbs目录下得Index文件
vi /root/www/nginx/bbs/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>bbs</title>
<head>
<body>
<H1>
www.bbs.com
</H1>
</body>
</html>
涉及到echo
操作的地方需要安装echo模块,使用--add-module
重新编译安装
./configure --prefix=/usr/local/nginx --add-module=/usr/local/nginx/modules/echo-nginx-module-master
make && make install
虚拟主机
所谓虚拟主机,在 Web 服务里就是一个独立的网站站点,这个站点对应独立的域名(也可能是IP 或端口),具有独立的程序及资源,可以独立地对外提供服务供用户访问。
在 Nginx 中,使用一个 server{} 标签来标识一个虚拟主机,一个 Web 服务里可以有多个虚拟主机标签对,即可以同时支持多个虚拟主机站点。
虚拟主机有两种类型:基于域名的虚拟主机、基于IP+端口的虚拟主机。
完全匹配虚拟主机
在 conf.d文件夹下创建vhostserver.conf
配置文件内容如下
server {
listen 80;
charset utf-8;
server_name www.abc.com;
location /{
alias '/root/www/nginx/abc/';
index index.html index.htm;
expires 7d;
}
}
server {
listen 80 ;
charset utf-8;
server_name www.bbs.com;
location /{
alias '/root/www/nginx/bbs/';
index index.html index.htm;
expires 7d;
}
}
修改host文件
更新配置文件后配置本地host
192.168.64.150 www.abc.com
192.168.64.150 www.bbs.com
访问测试
访问 www.bbs.com
我们发现访问不同的域名访问的地址是不一样的这样就像是有多个物理机一样。
通配符配置虚拟主机
虚拟主机还支持通配符方式进行配置
server {
listen 80;
charset utf-8;
server_name *.com;
location /{
default_type text/html;
echo "通配符在前";
}
}
server {
listen 80;
charset utf-8;
server_name www.abc.*;
location /{
default_type text/html;
echo "通配符在后";
}
}
访问测试
访问 www.abc.com 发现出现如下页面
虚拟主机匹配顺序
通过上面的实验可以得出如下结论
- 最高优先级:完全匹配
- 第二优先级:通配符在前
- 第三优先级:通配符在后
默认主机匹配
默认虚拟主机的作用就是:如果有多个访问的域名指向这台web服务器,但某个域名未添加到nginx虚拟主机中,就会访问默认虚拟主机(泛解析)
server {
# 将域名bbs.com 设置为默认虚拟主机
listen 80 default;
charset utf-8;
server_name www.bbs.com;
location /{
alias '/root/www/nginx/bbs/';
index index.html index.htm;
expires 7d;
}
}
使用未配置的域名或者IP地址访问,我们发现如果访问一个没有配置的虚拟主机就会跳到bbs的页面。
location的作用
location有“定位”的意思,根据请求不同的URL来进行不同的处理,在虚拟主机中(server),location配置是必不可少的,可以把网站不同的部分定位到不同的处理方式上。
location规则
location区段,通过指定模式来与客户端请求的URI相匹配
允许根据用户请求的URI来匹配定义的各location,匹配到时,此请求将被响应的location配置快中的配置所处理,例如做访问控制等功能
语法
location [修饰符] pattern {…}
常用的修饰符说明
修饰符 | 功能 |
---|---|
空 | 前缀匹配 能够匹配以需要匹配的路径为前缀的uri |
= | 精确匹配 |
~ | 正则表达式模式匹配,区分大小写 |
~* | 正则表达式模式匹配,不区分大小写 |
^~ | 精确前缀匹配,类似于无修饰符的行为,也是以指定模块开始,不同的是,如果模式匹配,那么就停止搜索其他模式了,不支持正则表达式 |
/ | 通用匹配,任何请求都会匹配到。 |
前缀匹配
没有修饰符表示必须以指定模式开始,指定模式前面没有任何修饰符,直接在location后写需要匹配的uri,它的优先级次于正则匹配
server {
server_name www.test.com;
charset utf-8;
location /abc {
default_type text/html;
echo "前缀匹配-abc...";
}
}
那么如下内容可以就可以正确匹配:
通用匹配
通用匹配使用一个 / 表示,可以匹配所有请求,一般nginx配置文件最后都会有一个通用匹配规则,当其他匹配规则均失效时,请求会被路由给通用匹配规则处理;如果没有配置通用匹配,并且其他所有匹配规则均失效时,nginx会返回 404 错误
server {
server_name www.test.com;
charset utf-8;
location /{
default_type text/html;
echo "通用匹配-default";
}
}
那么如下内容可以就可以正确匹配所有请求
精确匹配
精确匹配使用 = 表示,nginx进行路由匹配的时候,精确匹配具有最高的优先级,请求一旦精确匹配成功nginx会停止搜索其他到匹配项
server {
server_name www.test.com;
charset utf-8;
location = /abc {
default_type text/html;
echo "精确匹配-abc-accurate";
}
}
那么如下内容可正确匹配:
如下内容则无法匹配:
精确前缀匹配
精确前缀匹配的优先级仅次于精确匹配,nginx对一个请求精确前缀匹配成功后,停止继续搜索其他到匹配项
server {
server_name www.test.com;
charset utf-8;
location ^~ /abc {
default_type text/html;
echo "精确前缀匹配-abc-prefix";
}
}
那么如下内容可以就可以正确匹配:
正则表达式
正则匹配分为区分大小写和不区分大小写两种,分别用 ~ 和 ~* 表示;一个请求精确匹配和精确前缀匹配都失败后,如果配置有相关的正则匹配location,nginx会尝试对该请求进行正则匹配。需要说明的是正则匹配之间没有优先级一说,而是按照在配置文件中出现的顺序进行匹配,一旦匹配上一个,就会停止向下继续搜索。
区分大小写
~:表示指定的正则表达式要区分大小写,如:
server {
server_name www.test.com;
charset utf-8;
location ~ ^/abc$ {
default_type text/html;
echo "正则区分大小写-abc-regular-x";
}
}
那么如下内容可以正确匹配:
如下内容则无法匹配:
不区分大小写
~*:表示指定的正则表达式不区分大小写,如:
server {
server_name www.test.com;
charset utf-8;
location ~* ^/abc$ {
default_type text/html;
echo "正则不区分大小写-abc-regular-Y";
}
}
那么如下内容就可以正确匹配:
如下内容则无法匹配:
完整例子
server {
server_name www.test.com;
default_type text/html;
charset utf-8;
location = / {
echo "规则A";
}
location = /login {
echo "规则B";
}
location ^~ /static/ {
echo "规则C";
}
location ^~ /static/files {
echo "规则X";
}
location ~ \.(gif|jpg|png|js|css)$ {
echo "规则D";
}
location ~* \.js$ {
echo "规则E";
}
location /img {
echo "规则Y";
}
location / {
echo "规则F";
}
}
请求uri | 匹配路由规则 |
---|---|
http://www.test.com | 规则A |
http://www.test.com/login | 规则B |
http://www.test.com/register | 规则F |
http://www.test.com/static/a.html | 规则C |
http://www.test.com/static/files/a.txt | 规则X |
http://www.test.com/a.png | 规则D |
http://www.test.com/a.PNG | 规则F |
http://www.test.com/img/a.gif | 规则D |
http://www.test.com/img/a.tiff | 规则Y |
匹配顺序
匹配顺序和优先级,由高到底依次为:
- 带有“=”的精确匹配优先
- 正则表达式
- 没有修饰符的精确匹配
具体匹配规则如下:
- =精准匹配命中时,停止location动作,直接走精准匹配,
- 一般匹配(含精确前缀匹配)命中时,先收集所有的普通匹配,最后对比出最长的那一条
- 如果最长的那一条普通匹配声明为精确前缀匹配,直接此条匹配,停止location
- 如果最长的那一条普通匹配不是精确前缀匹配,继续往下走正则location
- 按代码顺序执行正则匹配,当第一条正则location命中时,停止location
注:有多个正则表达式出现时,按照它们在配置文件中定义的顺序
path匹配过程
假设http请求路径为 http://192.168.0.132:8088/mvc/index?id=2 ,匹配过程如下:
- 将整个url拆解为域名/端口/path/params
- 先由域名/端口,对应到目标server虚拟主机
- path部分参与location匹配,path = path1匹配部分 + path2剩余部分
- 进入location方法体内部流程。
- 若是静态文件处理,则进入目标目录查找文件:root指令时找path1+path2对应的文件;alias指令时找path2对应的文件
- 若是proxy代理,则形如proxy_pass=ip:port时转发path1+path2路径到tomcat;形如proxy_pass=ip:port/xxx时转发path2路径到tomcat。params始终跟随转发。
实际使用建议
#直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。
#这里是直接转发给后端应用服务器了,也可以是一个静态首页
# 第一个必选规则
location = / {
proxy_pass http://tomcat:8080/index
}
# 第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
# 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
alias /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
root /webroot/res/;
}
# 第三个规则就是通用规则,用来转发动态请求到后端应用服务器
# 非静态文件请求就默认是动态请求,自己根据实际把握
# 毕竟目前的一些框架的流行,带.php,.jsp后缀的情况很少了
location / {
proxy_pass http://tomcat:8080/
}