现在互联网web项目一般离不开分布式,访问量大的情况下,单台服务器一般是扛不住大量负载访问的(如单台tomcat目前最多能抗住200-500的并发量),既然一台不行那就搭建多台,性能不够,数量来凑。那接下来访问就可能有问题了,难道需要用户准备多个ip地址或者访问地址吗,显然这是不友好的,这样一个管理多个服务器的中间服务器出现了,Nginx就是其中的代表,它是一款优秀的代理服务器,通过它可以实现负载均衡,动静分离等。
关于代理
学习Nginx之前,需要了解下代理的概念,包括代理,正向代理和反向代理,参考博文学习了下。
(1)代理,前面已经学习过了静态代理和动态代理,简单来说就是让一个中间人来处理幕后大佬的工作,如明星的助手,老板的秘书等就是代理。
(2)正向代理,如翻墙就是正向代理的例子,访问国外某个网站访问不了,那可以先访问国外某个可以访问的服务器,然后通过可以访问的服务器再访问那个不可以访问的服务器,这就是正向代理。正向代理中,用户很清楚要访问的服务器地址是什么,正向代理对服务器隐藏了真实用户,它只知道请求来自代理服务器。
(3)反向代理,一般跟分布式集群服务器挂钩,用户在访问真实服务器前先访问一个中间服务器,它提供统一的地址,通过内部均衡算法,将请求分发到背后集群中的某台服务器。反向代理对用户隐藏了真实服务器的信息,跟正向代理相反。
Nginx的安装
(1)nginx的安装,可以去官网下载,地址:http://nginx.org/en/download.html,一般选择稳定版本,下面所有的操作均基于window系统。
(2)将下载好的压缩包解压到安装目录,注意目录中不要有中文和空格,解压完成即完成安装,使用nginx也有常用命令,如下:
nginx -v:查看版本
nginx -t:检查conf/nginx.xml文件配置是否有效,nginx.xml文件是核心配置文件,里面会配置动静分离,负载均衡等信息。
start nginx:启动ngnix
nginx -s quit:正常关闭nginx,nginx会处理完所有的请求后才关闭
nginx -s stop:立即关闭nginx
nginx -s reload:修改完nginx.xml后,可以使用此命令重新加载
以上命令可以写成脚本,放到bat文件中,通过点击bat文件实现上面的效果,类似tomcat启动执行startup.bat脚本,只是nginx下写的非常非常简单。
(3)nignx.conf配置,是使用nginx的关键,需要配置监听端口,location匹配然后转发到对应的服务器处理等。
http{ #代表处理http请求
#配置一个虚拟服务器
server{
#监听80端口,nginx的端口就是80
listen 80;
#此虚拟服务器接收对www.yangchaolin.com的访问,可以是网址也可以是ip地址
server_name www.yangchaolin.com;
#当访问/loc1资源时转到此配置处理
location /loc1{
规则1
proxy_pass 地址
index 主页
}#当访问/loc2资源时转到此配置处理
location /loc2{
规则2
proxy_pass 地址
index 主页
}
...
}
#其他Server配置
server ...
...
}
Ngnix小试牛刀
下面使用nginx,通过访问www.yangchaolin.com地址,分发到不同的tomcat服务器来处理,感受一下。
(1)先在本地准备三台tomcat,修改server.xml配置,分别使用8081,8082和8083端口。
修改server port为不一样。
修改tomcat端口分别为8081,8082和8083。
AJP 1.3 Connector 端口修改为不一样。
(2)修改nginx.xml内容,配置负载均衡。
# 实现负载均衡
server {
listen 80;
# 设置服务器地址
server_name www.yangchaolin.com;
location / {
# 代表通过代理转发到http://testnginx
proxy_pass http://testnginx ;
}
}
# upstream关键字,访问testnginx会跳转到下面的服务器,默认轮询访问
upstream testnginx {
# tomcat集群地址
server 127.0.0.1:8081 ;
server 127.0.0.1:8082 ;
server 127.0.0.1:8083 ;
}
(3)在三台tomcat服务器的webapp下,均创建news目录,里面放一个测试用的html,为了标识来自不同的tomcat,使用数字1 2 3。
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 </head> 5 <!--来自tomcat1 --> 6 <h2>this is from tomcat 1</h2> 7 <body> 8 </body> 9 </html>
(4)访问地址可以正常获取页面内容,刷新发现分别来自不同的tomcat服务器,这样就实现了负载均衡,默认是轮询访问,此外还有ip_hash、权重、最少连接数、url_hash,fair的访问方式,需修改nginx.xml文件,url_hash和fair暂时还没有测试过。
F12查看服务器变成了nginx。
ip_hash,如果nginx中配置ip_hash,则访问nginx的ip地址不变,则访问的的tomcat服务器就不会变,ip_hash底层使用了ip.hash()%tomcat服务器数目来分发服务器,这个算法应用很广,类似的应用还有redis的hash一致性计算,MapReduce中的map阶段的分区计算等。
# 配置ip_hash
upstream testnginx {
# abs(ip.hash)%tomcat服务器的数目,随机分发
ip_hash; # 负载均衡散列,只要ip地址不变,访问的tomcat服务器就不变
server 127.0.0.1:8081 ;
server 127.0.0.1:8082 ;
server 127.0.0.1:8083 ;
}
这样设置后,发现不管怎么刷,访问的tomcat返回的结果不会变说明来自一个服务器,下图status code显示304也说明发现访问的是同一个服务器并且返回结果不变就使用缓存了。这个设置可以解决web开发中session不能在集群共享的问题,当然,可以使用redis来保存session,只是ip_hash也是是一种解决方法。
设置权重,一般服务器有好坏新旧之分,一般来说好的服务器需要让他承受更多,为此可以为服务器设置权重,用weight=数字来设置,数字越大权重越大,如果设置为down代表不使用这个服务器。
upstream testnginx {
#使用weight权重
server 127.0.0.1:8081 weight=6;
server 127.0.0.1:8082 weight=2;
server 127.0.0.1:8083 down;
}
设置最少连接数, 即哪台服务器连接数最少,得到新的请求的几率越大,也是上述配置添加配置。
upstream testnginx {
# 可以使用least_conn
#least_conn
server 127.0.0.1:8081 ;
server 127.0.0.1:8082 ;
server 127.0.0.1:8083 ;
}
还有两种后续补充,暂时没有接触到。
location配置
关于location的配置,网上博文很多,直接摘抄过来测试,配置location后面会在springcloud微服务中设置网关集群也会用到。
匹配 | 说明 |
location= 路径 | 精确匹配,路径必须一模一样,首先进行精确匹配 |
locaton ^~ 路径 | 以这个路径开头的能匹配,其次匹配这个 |
location ~ 路径 | 区分大小写的路径匹配 |
locaton ~* 路径 | 不区分大小写的路径匹配 |
location / 路径 | 通用匹配,当上述规则都没有匹配到就最后匹配这个 |
注意~和~*按出现在配置文件中的位置来进行匹配,上述匹配规则只要哪个先匹配上,就按照匹配的规则处理请求,下面在上面tomcat集群基础上测试配置,均OK。
# 测试location匹配规则
server{
listen 80;
server_name www.testlocation.com;
# (1)精确匹配
#location = /news/1.html {
# proxy_pass http://127.0.0.1:8081;
#}
# (2)以路径开头
#location ^~ /news {
# proxy_pass http://127.0.0.1:8082;
#}
# (3)匹配大写小按正则匹配,所有以html结尾的
#location ~ \.html$ {
# proxy_pass http://127.0.0.1:8083;
#}
# (4)匹配不区分大写小按正则匹配,所有以html结尾的
#location ~* \.HTml$ {
# proxy_pass http://127.0.0.1:8081;
#}
# (5)最终匹配,当前面任何都匹配不上,就匹配这里
location / {
proxy_pass http://www.baidu.com;
}
}
(1)请求必须是www.testlocation.com/news/1.html,才代理到http://127.0.0.1:8081/news/1.html。
(2)请求必须以news开头,才能代理到http://127.0.0.1:8082,发现匹配部分路径会自动拼接到代理地址后面。
(3)请求中必须.html结尾,如www.testlocation.com/news/1.html,就可以访问到目标资源。
(3)请求需以.HTml结尾,但是不区分大小写,也就是说www.testlocation.com/news/1.HTML也可以访问到资源。
(5)当随便写一个上面四种都匹配不上的地址,则会自动跳转到百度,如www.testlocation.com/hehehe访问后跳到百度并提示错误,这是正常的,因为百度可能没有hehehe路径的资源。
动静分离
nginx还有一个重要的功能,那就是实现动静分离,即动态资源和静态资源分别交给不同的服务器来处理,充分发挥服务器的长处。一般动态资源(servlet,jsp本质上也是servlet)交给tomcat来处理,静态资源(html、css、js和图片等)交给nginx来处理,下面简单实现一下。
使用maven+springmvc来实现一个简单的动静分离。
(1)静态资源为sou.html页面,路径为F:/sou/sou.html。
<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta charset="utf-8" /> <title>Web应用虚拟目录映射</title> <!--添加简单样式--> <style type="text/css"> div{ font-size:20px; width:100%; height:30px; text-align:center; } #div1{ margin-top:150px; } #div2{ margin-top:10px; } #div3{ margin-top:10px; } #t1{ width:300px; height:30px; border:1px solid grey; } #t2{ width:100px; height:35px; font-family:'微软雅黑'; font-size:20px } </style> </head> <body> <form action="/nginxstatic/test/hello.action" method="GET"> <div id="div1">搜一下~要你所想!</div> <div id="div2"><input id="t1" type="text" name="question"></input></div> <div id="div3"><input id="t2" type="submit" value="提交"></input><div> </form> </body> </html>
maven项目使用IDEA打成war包后放到tomcat webapp下,自动解压,其中主要写了一个控制类,其他参考SSM整合的springmvc部分 https://www.cnblogs.com/youngchaolin/p/11647140.html。
package com.boe; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/test") public class MyController { @RequestMapping("/hello.action") public String test(String question){ if("clyang".equals(question)){ return "hello nginx static"; }else{ return "hello buddy"; } } }
nginx.conf中添加如下配置。
# 配置动静分离测试
server{
listen 80;
server_name www.static.com;
location / {
# 访问www.static.com匹配到了静态资源
root f://sou;
# 这个匹配就默认sou.html为主页,访问后直接到了主页
index sou.html;
}
location /nginxstatic {
proxy_pass http://localhost:8080/nginxstatic;
}
}
测试直接通过www.static.com访问静态资源OK,提前需要修改本地host文件。
尝试发送action请求访问动态资源,发现能返回正常的数据,action请求地址http://www.static.com/nginxstatic匹配location后变成http:localhost:8080/nginxstatic,再拼接上后面的地址,就进入了控制器进行处理,返回一个json字符串。
测试中静态资源html页面不在tomcat中,通过nginx配置在F盘,而动态资源放到了tomcat的webapp目录下,通过nginx可以将动态资源和静态资源联系起来使用,这就是动静分离的效果。
以上是对nginx入门的学习,后续完善补充。
参考博文:
(1)https://www.jianshu.com/p/0118f7b3344d 入门
(2)https://www.cnblogs.com/xingyunblog/p/9066865.html 详细,包含linux下的安装配置
(3)https://www.cnblogs.com/jiangyang/p/8485046.html location匹配