nginx和tomcat配置负载均衡和session同步
一.背景
因业务需求,现需配置多台服务器,实现负载均衡。
二.解决方案
使用 nginx + tomcat,在这一台应用服务器部署一个nginx和两个tomcat。通过nginx修改配置后reload不丢失未结束请求的特性,手工卸载、添加节点,实现用户无感的在线更新。
三.配置细节
1.准备2个tomcat,并分别设置好端口
分别修改2个tomcat的tomcat/conf/server.xml文件
<Server port="8105" shutdown="SHUTDOWN"> <Server port="8305" shutdown="SHUTDOWN"> -------------------------------------- <Connector port="8180" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Connector port="8380" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> --------------------------------------- <Connector port="8109" protocol="AJP/1.3" redirectPort="8443" /> <Connector port="8309" protocol="AJP/1.3" redirectPort="8443" />
小提示:可以通过以下方法修改Tomcat的启动窗口的标题,来直观判断启动的是哪个Tomcat
本机Tomcat版本(8.0.52) 其他版本修改方法可能略有不同
2.nginx代理、负载均衡配置
首先到Nginx官网下载Nginx,Nginx官网链接 如图
1.8版本较为稳定,因此我们选择该版本
下载至本机,并解压到任意不包含中文的路径下
直接启动Nginx根目录下的Nginx.exe即可启动服务,默认端口为80,若设备的80端口未被占用,用浏览器打开http://127.0.0.1即可看到如下页面
若端口被占用,修改Nginx的端口为其他未被占用的端口即可,配置文件在“nginx/conf/nginx.conf”
修改端口:http > server > listen 修改此处即可
多服务器配置:upstream 参照以下代码配置即可
注意:此处的server不能加 ‘http://’ ,否则会报错
代理配置 http > server > proxy_pass
注意:代理的名称即 upstream 的名称
权重配置 在server后面追加 weight= ** ; 即可
按照如下图的配置,Nginx每收到4个请求,会将其中的3个请求发送给8180 , 将另外一个发送给 8380
# 在这儿配置多个服务器
upstream localtomcat { #注意:upstream的名称不能有下划线,Nginx不能识别
server 127.0.0.1:8180 weight=3; #权重配置
server 127.0.0.1:8380 weight=1;
}
server {
listen 8888; # nginx监听8888端口
# 特别注意server_name配置,这儿在实际使用中配置多个域名,比如test.com www.test.com,
server_name localhost 127.0.0.1 luxingda.top;
location / {
root html;
index index.html index.htm;
proxy_pass http://localtomcat; #用http://+upstream的名称来使用
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
默认负载均衡策略就是平均分配请求。
Nginx常用命令 (注意:要在Nginx目录下执行)
检查配置文件 nginx -t
重新加载配置 nginx -s reload
停止Nginx服务 nginx -s stop
重新启动 nginx -s reload
每次修改配置文件后,不用重启Nginx,使用 nginx -s reload 重新加载配置即可
3.测试session没有同步的效果
修改两个tomcat种的/webapps/ROOT/index.jsp为
<%@page contentType="text/html;charset=UTF-8" %>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head>
<title>Luxd负载均衡搭建~</title>
</head>
<body>
<div id="div1" style="color:red;font-size:35px"></div>
<br/>
<script>
var str = '<%="http://"+request.getLocalAddr()+":"+request.getLocalPort()+"" %>';
var port = '<%=request.getLocalPort()%>';
//alert(str);
document.getElementById('div1').innerHTML = '当前服务: '+str;
document.title = 'Luxd负载均衡搭建 - ' + port;
</script>
<% session.setAttribute("Luxd","Luxd"); %>
<% out.println("<font size='4'>sessionid is<font>"); %>
<%=session.getId() %><br/>
<% out.println("sessiontime is"); %>
<%=session.getCreationTime() %>
</body>
</html>
启动tomcat8180、tomcat8380、nginx,在浏览器访问http://localhost:8888,
结果一个是逐一访问2个Tomcat,session的id不一致。
此时虽然实现了负载均衡,但是session并未同步到不同的Tomcat上,传统非前后端分离的项目中不可避免的用到了session,因此我们要想办法同步session
4.tomcat配置session同步
修改2个tomcat的tomcat/conf/server.xml文件,在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="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"/> <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/> </Cluster>
5.war应用设置需要session同步
修改2个tomcat的tomcat/webapps/ROOT/WEB-INF/web.xml文件
在</web-app>之前添加标签 (注意,该标签在<web-app>标签内部)
<distributable/>
6.再次验证session同步
在浏览器再访问http://localhost:8888,结果就是tomcat8180和tomcat8380交替访问,但sessionId相同了。
7.正式应用发布
把项目分别发布到tomcat8180和tomcat8380。
四.模拟更新发布程序
正常的使用系统,验证业务操作正常。
模拟更新发布程序才是重点内容:
第一步
修改nginx/conf/nginx.conf文件,注释了Tomcat8180.
upstream localtomcat{
#server 127.0.0.1:8180;
server 127.0.0.1:8380;
}
第二步
重启nginx,输入nginx -s reload
第三步
确认Tomcat8180里面请求都已经全部结束(查看Tomcat8180控制台)
第四步
关闭Tomcat8180,发布程序并重启。
第五步
修改nginx/conf/nginx.conf文件,打开Tomcat8180,注释Tomcat8380.
upstream localtomcat{
server 127.0.0.1:8180;
#server 127.0.0.1:8380;
}
后面继续按照第二步、第三步、第四步,实现Tomcat8380的手动发布。
第六步
修改nginx/conf/nginx.conf文件,打开Tomcat8180和Tomcat8380.
upstream localtomcat {
server 127.0.0.1:8180;
server 127.0.0.1:8380;
}
第七步,重启nginx,输入nginx -s reload
五.总结
本次只是描述了整个配置过程,缺少了详细的解释,后面有时间陆续补充。