一台主机nginx做代理,两台tomcat主机做负载均衡
首先两台tomcat主机安装对应的安装包
yum install -y java-1.8.0-openjdk-devel tomcat tomcat-webapps tomcat-admin-webapps tomcat-docs-webapp
修改tomcat_users.xml增加三段,以便使用自带的两个应用
<role rolename="admin-gui"/>
<role rolename="manager-gui"/>
<user name="admin" password="admin" roles="admin-gui,manager-gui"/>
在tomcat服务器上创建一个应用
mkdir -pv /var/lib/tomcat/webapps/test/{WEB-INF,META-INF,calsses,lib}
然后创建应用程序jsp文件
在A主机上
<%@ page language="java" %>
<html>
<head><title>TomcatA</title></head>
<body>
<h1><font color="red">TomcatA.magedu.com</font></h1>
<table align="centre" border="1">
<tr>
<td>Session ID</td>
<% session.setAttribute("magedu.com","magedu.com"); %>
<td><%= session.getId() %></td>
</tr>
<tr>
<td>Created on</td>
<td><%= session.getCreationTime() %></td>
</tr>
</table>
</body>
</html>
在B主机上
<%@ page language="java" %>
<html>
<head><title>TomcatB</title></head>
<body>
<h1><font color="blue">TomcatB.magedu.com</font></h1>
<table align="centre" border="1">
<tr>
<td>Session ID</td>
<% session.setAttribute("magedu.com","magedu.com"); %>
<td><%= session.getId() %></td>
</tr>
<tr>
<td>Created on</td>
<td><%= session.getCreationTime() %></td>
</tr>
</table>
</body>
</html>
在httpd代理服务器上配置httpd服务
基于httpd的代理
<VirtualHost *:80>
ServerName node1.lvqing.com
ProxyRequests Off #关闭正向代理
ProxyVia on #是否在响应报文中加via
ProxyPreserveHost On #是否将请求报文首部一并转给后端
<Proxy *>
Require all granted
</Proxy>
ProxyPass / http://192.168.31.200:8080/ #把根反代给指定主机
ProxyPassReverse / http://192.168.31.200:8080/ #如果后端主机返回重定向>是否让客户端知道
<Location />
Require all granted
</Location>
</VirtualHost>
访问没有问题
换一种代理方式ajp代理,使用前可使用httpd -M查看是否启用proxy-ajp模块,没有的话需要手动加载
注意:ajp的代理端口是8009
<VirtualHost *:80>
ServerName node2.lvqing.com ProxyRequests Off
ProxyVia On
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / ajp://192.168.31.200:8009/
ProxyPassReverse / ajp://192.168.31.200:8009/
<Location />
Require all granted
</Location>
</VirtualHost>
同样代理到了,ajp代理相对于httpd代理更安全,客户端除非经过代理服务器否则无法与tomcat通信
image.png
但是前面都没有实现负载均衡的功能,接下来我们来编辑配置
首先是nginx的负载均衡,编辑配置文件添加一段
upstream tcservs {
hash $request_uri consistent; #使用uri一致性哈希算法保持会话粘性
#hash $cookie_name consistent 对cookie做哈希也可以
server 192.168.31.200:8080;
server 192.168.31.201:8080;
}
vim /etc/nginx/conf.d/lvqin.conf
server {
listen 80;
server_name node1.lvqing.com;
location / {
proxy_pass http://tcservs;
}
}
然后是httpd的负载均衡需要proxy_balancer_module模块
balancer的详细语法可以查看http://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
#相当于在cookie中加上ROUTEID以求实现session sticky
如果第一次访问的是tomcatA则下次再访问cookie会被注入route=TomcatA以便绑定
<proxy balancer://tcsrvs>
BalancerMember http://172.18.100.67:8080 route=TomcatA loadfactor=1
BalancerMember http://172.18.100.68:8080 route=TomcatB loadfactor=2
ProxySet lbmethod=byrequests
ProxySet stickysession=ROUTEID
</Proxy>
<VirtualHost *:80>
ServerName node1.lvqing.com
ProxyVia On
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / balancer://tcsrvs/
ProxyPassReverse / balancer://tcsrvs/
<Location />
Require all granted
</Location>
</VirtualHost>
还可以启用balancer的管理接口
在上面定义的虚拟主机中添加
<Location /bstatus>
SetHandler balancer-manager
ProxyPass !
Require all granted
</Location>
可以看到图片
image.png
然后负载均衡的目的就达到了很简单,难题是如何保持会话,一共三种方式:
会话保持:
(1) session sticky
source_ip
nginx: ip_hash
haproxy: source
lvs: sh
cookie:
nginx:hash
haproxy: cookie
(2) session cluster:delta session manager
(3) session server:redis(store), memcached(cache)
tomcat自己支持第二种会话集群的方式内部有一个cluster的组件,但这种方式只适用于较小规模的集群。
编辑两台主机的配置文件server.xml添加cluser组件
注意:cluster组件应当放在host或engine组件中,多播地址应该一致
<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="225.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>
这样子我们前端代理的会话绑定就可以取消了
注意:绑定的地址为auto时,会自动解析本地主机名,并解析得出的IP地址作为使用的地址;
需要为test提供一个web.xml配置文件并添加上distribution,属性,意思是为test做分布式会话
因为这个test是我们自己创建的没有web.xml所以复制一个到/var/lib/tomcat/webapps/test/WEB-INF中添加一段<distributable/>
查看TomCatA的日志信息可以发现B已经成问会话集群的成员了
接下来不管我们代理到后端的哪一台主机但session的ID都不会变
httpd除了http,ajp还有第三种协议连接jk,但现在已经不怎么使用了,这里实验测试一下安装httpd第三方模块提供服务
得到源码
tar xvf tomcat-connectors-1.2.40-src.tar.gz
./configure --with-apxs=/usr/bin/apxs
安装时需要指定apxs的位置,这个服务是为httpd的第三方模块提供一个接口
make && make install
最后提示我们修改模块的执行权限,照做
chmod 755 /usr/lib64/httpd/modules/mod_jk.so
但现在还不会自动装载进去,需要我们手动编辑一个模块加载文件
vim /etc/httpd/conf.modules.d/mod_jk.conf
loadModule jk_module /usr/lib64/httpd/modules/mod_jk.so
然后我们httpd -M就可以看到这个模块了
image.png
接下来我们实验使用memcache来做第三方会话管理器msm
在两台tomcat主机上安装memcache,然后去网站上下载管理器软件http://repo1.maven.org/maven2/de/javakaffee/msm/
下载后的jar类文件放在tomcat的类文件目录即可
/user/share/java/tomcat
然后修改server.xml文件在host或者context中添加一个manager
<Context path="/var/lib/tomcat/webapps/test" docBase="/var/lib/tomcat/webapps/test" reloadable="true">
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:192.168.31.200:11211,n2:192.168.31.201:11211"
failoverNodes="n2"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"
/>
</Context>
ls
javolution-5.5.1.jar
memcached-session-manager-1.8.2.jar
memcached-session-manager-tc7-1.8.2.jar
msm-javolution-serializer-1.8.2.jar
spymemcached-2.10.2.jar
#全都放在/user/share/java/tomcat文件中
mv *.jar /user/share/java/tomcat
启动tomcat后接下来我们就可以看到实验效果了
网友评论