nginx反向代理和重定向以及正则
反向代理使用tomcat作为演示,因此需要安装
一、安装tomcat:
1、首先在机器机器上安装tomcat,直接yum即可(演示用),如下:
yum -y install tomcat
2、在/usr/share/tomcat/目录下创建ROOT文件夹,然后编辑一个index.html文件作为入口,如下:
#linux安装tomcat没有默认页面,因此需要人为创建
mkdir -p /usr/share/tomcat/ROOT
echo "I am Tomcat" >> /usr/share/tomcat/ROOT/index.html
#yum安装的tomcat实际应该是通过软连接到/var/lib/tomcat路径下
3、通过浏览器加上8080端口访问如下:

二、配置nginx反向代理:
1、根据默认url地址匹配:
在conf.d路径下新增配置文件gong.com.conf,添加内容如下:

说明:www.gong.com为自定义域名,需要在windows本地添加解析,通过此域名的80端口访问将代理到10.9.2.80的8080端口,也就是tomcat服务上

2、根据不同的url地址进行匹配:
编辑gong.com.conf文件,配置不同的url条件,如图:

在/usr/share/tomcat/webapps/目录下新建项目文件夹projectA和projectB,并在内部创建文件index.html,内容分别为:


重新加载nginx配置文件或者重启nginx,然后访问如下:


注意:webapps一般会有一个ROOT目录,此目录下也可以放项目,访问的时候不需要加项目名,例如直接放一个index.html,访问时直接通过IP和端口即可,如果直接放在webapps目录下,访问的时候需要加上项目名去访问
url匹配又分为两种情况:
- 带正则的url匹配,如上图中 ~ /projectC/
- 不带u正则的url匹配,没有正则符号
当用正则进行匹配的时候,代理的地址只能到ip+port,后面不能再有路径否则报错,如下:

上图中的条件通过正则匹配,代理地址的端口后面也加了路径/projectC/,此时nginx配置文件将报错:nginx: [emerg] “proxy_pass” cannot have URI part in location given by regular expression
解决方案就是取消正则匹配,按照通用匹配方式,如图:

说明:如果代理地址后面加了路径,那么此路径将会替换匹配条件中的路径,通过地址匹配地址访问,可以看到还是会跳转到代理路径去,如图:

3、同一个url代理到多个地址上:
通过域名匹配条件代理到后端多台服务器上,如图:

注意:proxy_pass代理得地址project后面不能有”/” ,要直接是分号;如果加了”/”,那么路由project会被省略
每次访问会轮询两台得方式实现返回数据,如图:


反向代理常用参数:
- proxy_http_version 1.0 ; #Nginx服务器提供代理服务的http协议版本1.0,1.1,默认设置为1.0版本,可改为1.1
- proxy_connect_timeout 10; #nginx服务器与被代理的服务器建立连接的超时时间,默认60秒
- proxy_read_timeout 10; #nginx服务器向被代理服务器组发出read请求后,等待响应的超时间,默认为60秒。
- proxy_send_timeout 10; #nginx服务器向被代理服务器组发出write请求后,等待响应的超时间,默认为60秒。
- proxy_ignore_client_abort on; #客户端断网时,nginx服务器是否中断对被代理服务器的请求。默认为off。
- proxy_next_upstream timeout; #反向代理upstream中设置的服务器组,出现故障时,被代理服务器返回的状态值。
- proxy_set_header Host $host; #$host就是nginx代理服务器
- proxy_set_header X-Real-IP $remote_addr; #$remote_addr的值为客户端的真实ip
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;#也可以获取真实IP
- keepalive_timeout 65; #连接超时时间,默认为75s,可以在http,server,location块。
- proxy_set_header Origin “”; #允许跨域
三、Nginx配置重定向
Nginx可以通过return和rewrite两种方式来实现重定向,Nginx服务器IP地址:10.9.2.247与jenkins在同一台机器上
1、使用return来实现重定向
return配置位置:server、location、if
return参数有三种方式:
- return code url重定向
- return url重定向 #临时重定向,返回302
- return code “文本内容” 返回状态码以及文本
1.1、下面例子使用第一种参数将url永久重定向到jenkins页面,如图:

注意:return后面的http地址结尾有没有”/”都没关系,因为只要匹配了路径/jenkins就会请求过来
接下来通过http://10.9.2.247/jenkins来请求,可以看到已经重定向到jenkins页面,如图:

下面例子是将80端口重定向到443,如下:
server {
listen 80;
server_name www.abc.top abc.top;
return 301 https://www.abc.top$request_uri;
}
- request_uri:表示保留原始请求的url,比如客户端请求的地址是http://www.abc.top/path?param1=value1,那么将重定向到https://www.abc.top/path?param1=value1,会把参数带过去的
1.2 、下面例子是使用第二种参数将url重定向到百度页面,如图:

此时通过浏览器访问http://10.9.2.247/url/ 将重定向到百度页面,查看返回状态码,如图:

1.3、下面例子是使用第三种参数,返回状态码和文本,如图:

通过浏览器访问http://10.9.2.247/test 将下载test文件,查看此文件内容如下:

注意:return后面只有是200的时候才会下载,其余的不会
2、使用rewirte实现重定向
rewrite配置位置:server、location、if
rewrite如何使用在server,那么对全局有效,使用在location和if只针对这两个有效
语法如下:
rewrite regex replacement [flag]
- regex:正则表达式
- replacement:重写的内容,也就是跳转后的内容
- flag:rewrite的标记
常用的flag标记如下:
| last | 本条规则匹配完成后,不终止重写后的url匹配,一般用在 server 和 if 中 |
| break | 本条规则匹配完成即终止,终止重写后的url匹配,一般使用在 location 中 |
| redirect | 返回302临时重定向,浏览器地址栏会显示跳转后的URL地址 |
| permanent | 返回301永久重定向,浏览器地址栏会显示跳转后的URL地址 |
演示例子之前我们先通过yum安装一个httpd,然后修改端口为88,并修改默认界面内容如下:
vim /var/www/html/index.html #this is a httpd pag
启动httpd后,通过浏览器访问,如下:

本例子中Nginx和httpd都在同一台机器,端口分别为80和88,下面举几个例子演示下,更多用法可查官方文档或自行网络查找研究
rewrite放在location{}中
2.1 、下面例子中,请求路由为/,也就是默认根路由,如图:

此时通过浏览器访问http://10.9.2.247,可以看到已经跳转到httpd,如图:

在不改变上图中rewrite规则情况下,无论location中路由变成什么,最终都是重定向到httpd的默认页面
2.1 、在httpd默认界面/var/www/html目录下创建test目录,添加index.html文件,内容如下:
mkdir -p /var/www/html/test
echo "this is a test page about httpd!!!" > /var/www/html/test/index.html
修改location和rewrite规则,如图:

通过浏览器访问http://10.9.2.247/test ,查看浏览器响应结果如下:

从上图看出,当请求路由为/test,实际是跳转到了httpd根路径下的test目录的index.html文件,为什么会这样呢?因为rewrite中的正则(.*) 前面并无其他内容,因此此时匹配的就是上面的路由test,而$1正好对应的是(.*)的内容,因此实际请求路径就变成了10.9.2.247:88/test
注意:在rewrite的正则中,如果有$1、$2,那么实际匹配的是()中的内容,比如:
# $1、$2....只能匹配括号内容,记住,只能匹配括号内容
rewrite /(abc)/(def) https://example.com/$1/$2 #匹配路径为https://example.com/abc/def
rewrite /abc/(def) https://example.comf/$1 #匹配路径为https://example.com/def
2.3 、修改上述rewrite规则,添加一段路径,如图:

此时通过浏览器请求http://10.9.2.247/test/index.html,将跳转到httpd默认路径下的index.html,因为$1只能匹配括号的内容,此时(.*)匹配的内容就是index.html,因此实际重定向的路径就是http://10.9.2.247:88/index.html,^/test表示匹配以test开头的路由,location中是test,这里匹配的开头也要是test,不能所以写,会报错

注意:上面的location中路由是/test还是/test/对结果都没有影响,$1只匹配括号里的
2.4、修改rewrite规则,增加一个路径abcd,再次查看结果,如图:

浏览器中输入http://10.9.2.247/test/abcd/index.html,实际重定向的路径是http://10.9.2.247:88/index.html,因为$1匹配的只是()中的内容

注意:rewrite中的路由有test,location中路由也有test,此时rewrite中的test会覆盖location中test
2.5、修改location路由和rewrite规则,如图:

从上图看出location路由和rewrite路由不同,此时请求的时候需要将rewrite路由一起加上,请求路径http://10.9.2.247/test/def/abcd/index.html将重定向到http://10.9.2.247:88/index.html

注意看,上面的rewrite的/abcd/前面是没有”^”的,如果加了这个”^”后,再按照上面的路径请求就会异常,因为”^”表示匹配开头,加了后表示请求路由以abcd开头,那么请求路径就会变成http://10.9.2.247/abcd/index.html,但是location中也没有abcd这个,所以请求也不会成功,因此要么不加”^”,在请求的时候直接将rewrite路由加在location路由后面,要不就像上面2.4中的那样,把location的路由也写在rewrite中,并加前缀”^”匹配
2.6,下面例子使用$1和$2获取两个参数,如图:

浏览器请求http://10.9.2.247/test/def/abc/abc.html,结果如下:

上图中的rewrite有两个括号内容,那么将分别对应$1和$2,因此实际请求将匹配到http://10.9.2.247:88/abc/abc.html
rewrite放在if{}中
修改上面的nginx配置文件,如下:

- 41行:定义两个域名
- 44行:如果请求域名为www.abc.com,那么将通过rewrite重定向否则直接请求nginx的根路径文件
- 45行:重定向到httpd路径下
- 47行:默认的Nginx根路径
通过浏览器访问www.def.com,可以看到跳转到了Nginx的默认界面,如图:

通过浏览器访问www.abc.com,可以看到重定向到httpd页面,如图:

rewrite放在server{}中
修改Nginx配置文件,将rewrite放在server中,如图:

上图中将rewrite放在server中,那么此时这个重定向将对全局生效,此时通过域名访问将重定向到httpd的默认界面,如图:

常用的Nginx正则表达式
| ^ | 匹配输入字符串的起始位置,以什么开头 |
| * | 匹配前面的字符零次或多次。如”01*”能够匹配到”0″、”01″、”011″、”0111…….” |
| + | 匹配前面的字符一次或多次。如”01*”能够匹配到”01″、”011″ |
| ? | 匹配前面字符零次或一次。如01?只能能够匹配到”0″、”01″ |
| . | 匹配除”\n“之外的任意一个字符,若要匹配包括”\n“在内的任意字符则使用”[.\n]“之类的表达式 |
| \ | 转义符 |
| \d | 匹配出数字效果于[0-9]一致 |
| \s | 空白符 |
| \w | 任意单词字符包括下划线 |
| {n} | 匹配前面表字符n次 |
| {n,m} | 匹配前面字符n到m次 |
| [] | 定义匹配的字符范围 |
| [c] | 匹配单个字符c |
| [a-z] | 匹配a-z小写字母任意一个 |
| [a-zA-Z0-9] | 匹配范围大小写字母及数字 |
| () | 看成整体匹配 |
| {n,} | 匹配前面字符不少于n次 |
nginx1.13版本的ssl配置内容如下:
ssl_certificate /etc/nginx/ssl/www.wantian.top.pem;
ssl_certificate_key /etc/nginx/ssl/www.wantian.top.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;


