一、什么是负载均衡
当一台服务器的单位时间内的访问量越大时,服务器压力就越大,大到超过自身承受能力时,服务器就会崩溃。为了避免服务器崩溃,让用户有更好的体验,我们通过负载均衡的方式来分担服务器压力。
我们可以建立很多很多服务器,组成一个服务器集群,当用户访问网站时,先访问一个中间服务器,在让这个中间服务器在服务器集群中选择一个压力较小的服务器,然后将该访问请求引入该服务器。如此以来,用户的每次访问,都会保证服务器集群中的每个服务器压力趋于平衡,分担了服务器压力,避免了服务器崩溃的情况。
二、负载均衡实现的几种方式
1. 轮询(默认)
系统默认处理方式,每一个请求按照时间顺序分配到不同的服务器上面,如果有服务器当掉会自动剔除。
upstream tomcatCluster
{
server 127.0.0.1:8001
server 127.0.0.1:8002
}
2.weight
指定轮询等级,weight和被访问几率成正比,用于服务器性能不均更好的调配资源
upstream tomcatCluster
{
#这里是tomcat的地址,weight越大,访问机率越大。
server 127.0.0.1:8001 weight=1
server 127.0.0.1:8002 weight=3
}
3比1大所以分配到3那台服务器的几率更大
(1).负载均衡的实现
步骤
- 修改两个Tomcat的端口,并启动
- 修改Nginx的配置文件
- 开启Nginx的服务
- 检查是否成功
- 关闭Nginx服务
实际操作
1.修改Tomcat端口
打开servlet.xml配置文件
注意:如果需要一台电脑开多个Tomcat,那就必须要保证(每个配置文件中需要改3个端口)需要让这些端口都不相同也不能修改成已经被别的程序占用的端口。
第一处
<Server port="8005" shutdown="SHUTDOWN">
第二处
<Connector port="8001" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8" />
第三处
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
2.进行匹配tomcat路径,在Tomcat启动文件上配置启动路径配置文件
在配置文件的最上面加上配置好的路径
set TITLE="tomcat001"
set CATALINA_BASE="D:\resources\tomcat001"
set CATALINA_HOME="D:\resources\tomcat001"
3.修改Nginx的配置文件
4.启动两个Tomcat
两个Tomcat启动成功
5.启动Nginx服务
启动成功
6.测试是否成功(在网页上输入自己的ip和Nginx设置的端口)
如上图表示成功:可以通过同一个URL可以访问,但是有两个Tomcat都会对其进行处理,达到负载均衡
如若未成功请仔细检查配置文件是否配置正确
7.关闭Nginx服务
3.ip_hash
上述方式存在一个问题就是说,在负载均衡系统中,假如用户在某台服务器上登录了,那么该用户第二次请求的时候,因为我们是负载均衡系统,每次请求都会重新定位到服务器集群中的某一个,那么已经登录某一个服务器的用户再重新定位到另一个服务器,其登录信息将会丢失,这样显然是不妥的。
我们可以采用ip_hash指令解决这个问题,如果客户已经访问了某个服务器,当用户再次访问时,会将该请求通过哈希算法,自动定位到该服务器。
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
upstream backserver {
ip_hash;
server 192.168.0.14:88;
server 192.168.0.15:80;
}
4.Tomcat完成session共享
原理:就是有几个Tomcat,就把session复制到几个Tomcat上面,只要有一个Tomcat中的session发生变化,其他Tomcat中的session跟着同步变化,保证所有用户的session在所有的Tomcat中都存在而且相同。这样一来无论用户的请求被分配到哪个Tomcat都是无所谓的,因为所有的Tomcat中都有他们存放的session
注:相当于每一个Tomcat上面都有你登录的session
1.创建一个web项目(eclipse或者idea)
在web根目录创建一个index.jsp内容如下
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
SessionID:<%=session.getId()%>
<BR> SessionIP:<%=request.getServerName()%>
<BR> SessionPort:<%=request.getServerPort()%>
<%
out.println("This is Tomcat Server 111");
%>
</body>
</html>
为了便于观察记得修改一下输出语句,进行不同的Tomcat的区分
因为测试session共享,需要准备两个war包内容输出内容不相同的
完成之后记得在web.xm里面加上一个节点<distributable/>
,放在<display-name>
下面
2.复制一个tomcat到不同文件夹下面
注:两个文件里面是一样的Tomcat,但是两个文件夹的名字不一样
导出两个输出不一样的War包
导出之后放到Tomcat里面的webapps文件夹里面
修改Tomcat文件中conf文件夹中的servlet.xml
找到:
找到图片上面这一行,大约在105行左右添加一下内容
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
channelSendOptions="8">
<Manager className="org.apache.catalina.ha.session.DeltaManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"/>
<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<Membership className="org.apache.catalina.tribes.membership.McastService"
address="228.0.0.4"
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="auto"
port="4000"
autoBind="100"
selectorTimeout="5000"
maxThreads="6"/>
<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
</Sender>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
</Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=""/>
<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>
<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
注:两个Tomcat的配置文件都需要添加这段代码
3.修改Tomcat端口也是在servlet.xml中修改
tomcat01修改
tomcat一样的方式修改
4.修改Tomcat启动路径
打开tomcat的bin文件夹,对startup.bat文件修改
在文件最上面添加启动路径:
set TITLE="tomcat001"
set CATALINA_BASE="D:\tomcat_session\tomcat001"
set CATALINA_HOME="D:\tomcat_session\tomcat001"
注:记得两个都要修改加上
5.启动Tomcat
6.修改Nginx.conf配置文件
修改Nginx路径下conf路径下nginx.conf文件
7.启动Nginx服务
8测试是否成功
在浏览器输入ip端口号以及自己的Url进行测试
测试成功:两个不同的Tomcat
,但是是一样的session,session共享成功。
9.关闭Nginx
关闭成功
优点:实现简单,没有什么花里胡哨的操作。如果集群中的tomcat的个数不多,而且用户没有那么多的时候可以选择这种方式。
缺点:只要Session数据有变化,就需要将数据同步到所有其他机器上,机器越多,同步带来的网络带宽开销就越大;当用户很多时,每台机器用于保存Session数据的内容占用会很严重,那么这个缺点该怎么处理和解决啊?