一.背景
公司使用的是springMVC+spring+Mybatis+Oracle技术,平台封装支持多账套、单据号、定时任务等。业务系统部署在一台应用服务器里面的tomcat,连接一台数据库服务器的oracle11g。用户业务发生时间很离散,一天24小时都有可能操作系统。一般凌晨4点至8点之间,业务操作较少。最近系统没有完全稳定,bug处理、优化完善的发布次数较多,很难跟客户能够约到合适的时间发布。加上有不同公司通过多账套在使用系统,逐一联系并确认发布时间很困难。希望能够实现用户无感的在线更新。
二.解决方案
使用nginx+tomcat,在这一台应用服务器部署一个nginx和两个tomcat。通过nginx修改配置后reload不丢失未结束请求的特性,手工卸载、添加节点,实现用户无感的在线更新。
三.配置细节
1.准备2个tomcat,并分别设置好端口
分别修改2个tomcat的tomcat/conf/server.xml文件
<Server port="8105" shutdown="SHUTDOWN">
<Server port="8205" shutdown="SHUTDOWN">
--------------------------------------
<Connector port="8180" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
<Connector port="8280" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
---------------------------------------
<Connector port="8109" protocol="AJP/1.3" redirectPort="8443" />
<Connector port="8209" protocol="AJP/1.3" redirectPort="8443" />
2.nginx代理、负载均衡配置
修改nginx/conf/nginx.conf文件
在server节点之前先配置
upstream services { server 127.0.0.1:8180; server 127.0.0.1:8280; }
在server节点中修改location配置为
location / { proxy_pass http://services; }
我还修改了server节点中的端口,默认是80,我修改为了8080.
listen 8080;默认负载均衡策略就是平均分配请求。
3.测试session没有同步的效果
修改tomcat1/webapps/ROOT/index.jsp为
<%@page contentType="text/html;charset=GB2312" %> <html> <head> <title>ckl JSP~</title> </head> <body> <% out.println("<h2><font color='red'>this page on 25 !</font></h2>"); %> <br/> <% session.setAttribute("ckl.com","ckl.com"); %> <% out.println("<font size='4'>sessionid is<font>"); %> <%=session.getId() %><br/> <% out.println("sessiontime is"); %> <%=session.getCreationTime() %> </body> </html>
修改tomcat2/webapps/ROOT/index.jsp为
<%@page contentType="text/html;charset=GB2312" %> <html> <head> <title>ckl JSP~</title> </head> <body> <% out.println("<h2><font color='blue'>this page on 49 !</font></h2>"); %> <br/> <% session.setAttribute("ckl.com","ckl.com"); %> <% out.println("<font size='4'>sessionid is<font>"); %> <%=session.getId() %><br/> <% out.println("sessiontime is"); %> <%=session.getCreationTime() %> </body> </html>
启动tomcat1、tomcat2、nginx,在浏览器访问http://localhost:8080,结果一个是逐一访问2个jsp,session是2个。
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>之前添加标签
<distributable/>
6.再次验证session同步
在浏览器再访问http://localhost:8080,结果就是tomcat1和tomcat2交替访问,但sessionId相同了。
7.正式应用发布
把业务真实地点war分别发布到tomcat1和tomcat2。
四.成果验证
正常的使用系统,验证业务操作正常。
模拟更新发布程序才是重点内容:
第一步,修改nginx/conf/nginx.conf文件,注释了tomcat1.
upstream services { #server 127.0.0.1:8180; server 127.0.0.1:8280; }
第二步,重启nginx,输入nginx -s reload
第三步,确认tomcat1里面请求都已经全部结束,我就肉眼看还有跑的没了。
第四步,关闭tomcat1,发布程序并重启。
第五步,修改nginx/conf/nginx.conf文件,打开tomcat1,注释tomcat2.
upstream services { server 127.0.0.1:8180; #server 127.0.0.1:8280; }
后面继续按照第二步、第三步、第四步,实现tomcat2的手动发布。
第六步,修改nginx/conf/nginx.conf文件,打开tomcat1和tomcat2.
upstream services { server 127.0.0.1:8180; server 127.0.0.1:8280; }第七步,重启nginx,输入nginx -s reload
五.总结
本次只是描述了整个配置过程,缺少了详细的解释,后面有时间陆续补充。
感谢忠实粉丝周先生、唐先生的鞭策。感谢文章https://blog.csdn.net/Readiay/article/details/45393435提供了tomcat中Cluster配置的详细说明。还大量参考了文章http://blog.51cto.com/ckl893/1893848