架构是一个比较宏观的概念,是控制、管理代码层面实现这一面更好地工做的过程。接下来请先看看几个版本的架构示意图。html
如上图所示,理论上单个Tomcat并发容量是200~300左右,通过优化后的最多500。虽然单机Tomcat开发部署简单,但出点故障就不行了,例如出现单点故障后应用服务就不能够访问了。前端
如上图所示,提供备用11.4 IP,当IP请求来的时候进行IP轮询,第一个请求走12.3,第二个请求走11.4,下一个请求又走12.3依次轮询。这样不只解决了单点故障的问题,容量也提高了。但仍是存在一些缺点,例如:java
此架构图咱们在浏览器和Tomcat之间加了请求分发工具和负载均衡设备。将请求入口集中在nignx下管理,用nignx的反向代理/负载均衡的典型算法,随机将请求分发到不一样的Tomcat。外网仅暴露一个接口,而Tomcat没有暴露到外网,上面的所遇到的问题也获得了比较好的解决。但这样的架构离天衣无缝还差的很远,由于请求分发、负载均衡的设备只设置了一台,只要存在单台,那么单点故障也会存在。并且这是一个重要节点,负责一切请求,一旦出故障,全部服务不可用。因此就衍生了下一个架构.nginx
双机热备,解决了负载均衡的单机BUG问题。可是对外同一时刻只有一个在服务,一个负责请求,另一个随时待命,每隔一段时间作一次心跳检测负载均衡是否都存活。假如其中一个挂了,就要把虚拟IP改到另一个负载均衡设备(Nginx),这样就能够继续提供服务了,体现了高可用性。web
这样的架构算是还比较满意,但有存在的缺点:算法
接下来咱们一块儿来看看一套比较完善的方案数据库
这一套方案是基于双机热备 + DNS轮询,在DNS供应商作些手脚,户输入域名经过浏览器访问DNS服务器,获得一个虚拟IP,经过虚拟IP进入相应的双机热备份,下一个请求来了,就经过轮询,用下一个虚拟IP又进入了另一个虚拟IP对应的双机热备份。apache
最后,在实际开发中这一套方案能够承受起几百万的访问量,但仍是以实际压力测试和单点故障测试数据为准。单机Tomcat跑一个应用的美好时代一去不复返,但一个成熟的产品一天24小时都要不停机运行。后端
F5(硬件设备)实现浏览器
优势:很是快,可靠性高,并发量大
缺点:成本高,不方便,最致命的是不能将动态请求和静态请求分离
缺点:不能将动态请求和静态请求分离(不多用)
优势:可靠性高,能够动静请求分离
缺点:效率低
简介:这是一种反向代理软件,反响代理:将庞大的Tomcat服务器的IP隐藏,真正在工做的是Nginx(即服务器隐藏了,找了个代理),正向代理:即隐藏用户IP。
优势:很是快,可靠性高并发量大,更重要的是能够实现动态请求和静态请求分离
负载均衡所存在的问题:session ID会发生变化
原理:Nginx 动静分离简单来讲就是把动态跟静态请求分开,不能理解成只是单纯的把动态页面和静态页面物理分离。严格意义上说应该是动态请求跟静态请求分开,能够理解成使用Nginx 处理静态页面,Tomcat、 Resin 出来动态页面。
测试软件:jemeter
步骤:
1.建立一个简单的Servlet工程,打包成war并部署到Tomcat
ServletDemo类
test.jsp
2.下载jemeter
网址:https://jmeter.apache.org/dow... 解压而后bin目录下双击jmeter.bat.
3.添加线程组并填写参数
4.添加Http请求并填写参数
5.添加监听想要查看的选项
6.简单servlet项目测试结果:
图形结果图
察看结果树
聚合报告结果
7.超多条线程演示
测试过程当中能够偷偷查看一下任务管理器的数据由于线程数高了有些时候会致使电脑卡顿。
最后来看一下6000条线程下的聚合报告
当线程数很高的时候,Tomcat承受不聊了(受业务影响),其中Error表明错误率,Throughput表明Tomcat的吞吐量。因此说Tomcat承受能力是有限的。
若是有兴趣你能够到的Tomcat安路径下servlet.xml修改一些配置继续测试。固然也能够经过这里进行一些相关优化。
地址:http://nginx.org/ 找stable version版的下载,尽可能不要下载最新的
复制Tomcat并修改能够修改的端口(文件在conf的server.xml)。同时分别对应两个Tomcat的学习项目作个标记,好比第一台tomcat访问成功的界面显示“Hello,Tomcat 1 shide ”,第二台同理。这里记录一下我第二台Tomcatserver.xml的端口修改,以防时回查时忘记。
8005→8015 8080→8090 8009→8019 8443→8453
在文件中添加两个东西
1. upstream test-service{ server localhost:8080; server localhost:8090; } # upstream表示上游服务器,test-service填的是服务器集群名,这里取test-service。 2. proxy_pass http://test-service; # 意思是只有test-service下面的tomcat才能经过个人反向代理。
在浏览器输入上一篇文章的项目访问路径:http://localhost/test_war/test
首先会看到下图状况:
刷新一下结果以下图
发现每刷新一次浏览器Nginx就将请求发送到另外一个Tomcat,这体现出了负载均衡的轮询算法。接下来就介绍几种常见的负载均衡算法。
很公平的原则,即每次过来的请求都会分配到相应的tomcat,你们一次排队各入各的位置。若是没位置了又从头开始。
经过过必定范围的随机数来分发请求给相应的tomcat.当请求量很大时,接近轮询。
经过请求来源的IP计算相应的hashCode来分发给相应的Tomcat,只要IP不发生变更,请求分发的Tomcat也就固定了。
在轮询的基础上增长权重,好比,如今是tomcat1,tomcat2,此时tomcat2加权重4,那么轮询的顺序即tomcat1,tomcat2,tomcat2,tomcat2,tomcat2,tomcat2。
跟加权轮询相似同样的作法。好比,tomcat1,tomcat2,此时tomcat2增长权重为4,那么tomcat1,tomcat2,tomcat2,tomcat2,tomcat2,tomcat2,那么tomcat随机分发的时候分发的概率就增大。
根据后端服务器当前的链接状况,动态的选取当前积压链接数最少的一台服务器来处理当前请求。
Nginx负载均衡实战回顾,咱们采用了轮询以及另外几种常见的负载均衡算法实现了Nginx的效果,接下来咱们分别对两个Tomcat稍微改造一下。
操做:在界面上显示session ID
启动Tomcat和nginx并输入路径结果以下图,刷新界面以后会发现请求会分发到另外一个tomcat上,sessionId也会发生变化,再刷回到tomcat1的时候sessionId也会发生变化。因此这就出现了sessionId不一致的问题,大部分系统是要求用户登陆的,因为session的问题会致使用户登录以后每一次请求均可能要从新登陆,显然用户体验极差!!!
Tomcat)之间进行session同步
即应用服务器Tomcat之间session同步共享,可是应用服务器自己能力有限,再加session同步会带来网络开销。(具体操做百度:N个tomcat之间实现Session共享)。
基于(轮询 和 源地址哈希)算法(适合通常)
要设置ip hash算法(修改Nginx的conf文件:ip_hash ) 请求定位到同一台应用服务器,不切换tomcat。
修改以后重启nginx访问界面,多刷新几遍看看session是否会发生变化?
很显然session没有发生变化,同个浏览器内打开新标签访问路径也是同一个session。这方案虽然解决的session问题,可是不容灾了。由于若是定位到的那台应用服务器挂了,那么用户是没法访问的。
外置集中管理session(主流,其实就是相似单点登陆)
利用NoSQL数据库、Redis 实现session外置集中管理,将用户每次登陆以后的sessionId保存到NoSQL数据库或者Redis中,sessionid是能够标识一个用户的,咱们能够用用户的灯登陆信息(帐号密码、时间戳)生成一个token并设置加密、解密,用户登陆以后将token存到tomcat外面,须要用到session的时候就到外置的集中管理中取,为了请求能分发到相应用服务器,从外置集中管理中取token校验便可。这样就解决的session共享问题。
简单理解:动态请求是要访问数据库并进行后端服务操做的,而静态资源(HTML,JavaScript,CSS,img等文件)与后台应用分开部署,提升用户访问静态代码的速度,下降对后台应用访问。
项目改造
1.在tomcat1(我这里没有改,把8.5看成是1了)的webappstest_war下建立static文件夹并添加一张图
2.在jsp界面引用这张图片
3.启动tomcat 1并访问效果以下图
4.把静态资源文件放在nginx的html下并修改nginx.conf文件
这里要注意请求的路径必须和tomcat的下面一致
location ~ \.(gif|jpg|jpeg|png|bmp|swf)$ { root html; }
而后重启nginx并访问界面还会看到原来的界面。
刚开始架构图那里所提到的负载均衡的双机热备的存活检测方案其实就是keepalive这个玩意,官网只提供Linux版本的,弄起来仍是比较麻烦的,要想深刻了解的仍是百度咯。
这里贴上心跳检测原理图
主要是中间这个玩意,左右两边的主备nginx设备绑定到同一个Keepalive,Keepalive会根据上游请求的虚拟ip转发给主Nginx,定时检测主Nginx是否存活,否就立马将ip转到备用的Nginx。
1.轮询(默认)
每一个请求按时间顺序逐一分配到不一样的后端服务器,若是后端服务器down掉,能自动剔除。
2.weight
指定轮询概率,weight和访问比率成正比,用于后端服务器性能不均的状况。
3.ip_hash
每一个请求按访问ip的hash结果分配,这样每一个访客固定访问一个后端服务器,能够解决session的问题
4.fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
5.按访问的url的hash结果来分配请求,使每一个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
所谓四层就是基于ip+端口的负载均衡;
七层就是基于URL等应用层信息的负载均衡;
同理,还有基于MAC地址的二层负载均衡和基于IP地址的三层负载均衡;
换句话说,二层负载均衡会经过一个虚拟MAC地址接收请求,而后在分配到真实的MAC地址,三层负载均衡会经过一个虚拟IP地址接收请求,而后再分配到真实的IP地址,四层经过虚拟IP+端口接收请求,而后再分配到真实的服务器;
七层经过虚拟机的URL或主机名接受请求,而后再分配到真实的服务器。
优缺点 :
七层负载均衡也称为“内容交换”,也就是主要经过文中的正真有意义的应用层内容,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。
以常见的TCP为例,负载均衡设备若是要根据真正的应用层内容再选择服务器,只能先代理最终的服务器和客户端创建链接(三次握手)后,才可能接收到客户端发送的真正应用层内容的报文,而后再根据报文中的特定字段,再加上负载均衡设备设置的服务器选择方式,,决定最终选择的内部服务器,负载均衡设备在这种状况下,更相似于一个代理服务器,负载均衡和前端的客户端以及之后端的服务器会创建TCP链接,因此从这个技术原理上来看,七层负载均衡对负载均衡的设备要求更高,处理能力、精确率更加友好。