一.背景
因業務需求,現需配置多台服務器,實現負載均衡。
二.解決方案
使用 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
五.總結
本次只是描述了整個配置過程,缺少了詳細的解釋,后面有時間陸續補充。