首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Apache 2.2 + Tomcat 7 垂直集群實戰:mod_jk 負載均衡與 Session 複製全配置

     編輯:Java 綜合教學

Apache 2.2 + Tomcat 7 垂直集群實戰:mod_jk 負載均衡與 Session 複製全配置

單機多 Tomcat 實例(垂直集群)能充分利用多核 CPU 與大內存,避免 JVM 堆過大導致 GC 停頓。本文提供基於 Apache 2.2.25 + Tomcat 7.0.47 + mod_jk 1.2.31 的生產級配置全記錄,涵蓋模塊版本匹配、Worker 負載均衡、AJP 端口隔離、jvmRoute 粘性會話、DeltaManager Session 複製,助你快速搭建高可用集群。

一、版本匹配鐵律:避開啟動失敗大坑

  • mod_jk 必須與 Apache httpd 版本精確匹配:文件名含 httpd-2.2.3 即對應 Apache 2.2.x。
  • 下載 mod_jk-1.2.31-httpd-2.2.3.so → 重命名 mod_jk.so → 放入 $APACHE_HOME/modules/。
  • 錯誤現象:Cannot load modules/mod_jk.so、symbol not found 多為版本不匹配。

二、Apache 核心配置 (httpd.conf + mod_jk.conf + workers.properties)

1. httpd.conf 關鍵修改

ServerRoot "D:/Apache2.2"  # Apache 安裝根目錄
# 末尾引入 mod_jk 配置
Include "D:/Apache2.2/conf/mod_jk.conf"

2. mod_jk.conf

LoadModule jk_module modules/mod_jk.so
JkWorkersFile conf/workers.properties
JkLogFile logs/mod_jk.log
JkLogLevel info
JkRequestLogFormat "%w %V %T"
JkMount /* controller  # 所有請求轉發給 controller worker

3. workers.properties (核心負載均衡邏輯)

worker.list=controller

# 控制器:負載均衡器
worker.controller.type=lb
worker.controller.sticky_session=1           # 開啟粘性會話
worker.controller.error_escalation_time=0
worker.controller.max_reply_timeouts=10
worker.controller.balance_workers=jvm1,jvm2  # 後端 Tomcat 列表

# 後端 Tomcat 1
worker.jvm1.reference=worker.template
worker.jvm1.port=8009
worker.jvm1.host=localhost
worker.jvm1.lbfactor=5        # 權重 5
worker.jvm1.activation=A      # 激活狀態

# 後端 Tomcat 2
worker.jvm2.reference=worker.template
worker.jvm2.port=9009
worker.jvm2.host=localhost
worker.jvm2.lbfactor=1        # 權重 1
worker.jvm2.activation=A

# 通用模板
worker.template.type=ajp13
worker.template.socket_connect_timeout=5000
worker.template.socket_keepalive=true
worker.template.ping_mode=A
worker.template.ping_timeout=10000
worker.template.connection_pool_minsize=0
worker.template.connection_pool_timeout=600
worker.template.reply_timeout=300000
worker.template.recovery_options=3

關鍵參數解讀:

  • sticky_session=1:依賴 jvmRoute 實現會話粘滯,請求固定路由到同一 Tomcat。
  • lbfactor:權重比 5:1,Tomcat1 處理 5/6 流量。
  • ping_mode=A:定期探活,自動剔除失效節點。

三、Tomcat 雙實例配置:端口隔離與 jvmRoute

複製 Tomcat 目錄為 tomcat1、tomcat2,修改 tomcat2/conf/server.xml:

<!-- 1. 關閉端口 -->
<Server port="8015" shutdown="SHUTDOWN">

<!-- 2. HTTP 連接器 -->
<Connector port="8090" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />

<!-- 3. AJP 連接器 (mod_jk 通訊專用) -->
<Connector port="9009" protocol="AJP/1.3" redirectPort="8943" />

<!-- 4. Engine 綁定 jvmRoute (必須與 worker 名一致) -->
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm2">

tomcat1 保持默認 (8005/8080/8009),jvmRoute="jvm1"。

四、Session 複製:DeltaManager 集群配置

在兩個 Tomcat 的 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="4001" 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.JvmRouteSessionIDBinderListener"/>
    <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>

核心組件:

  • DeltaManager:全量/增量 Session 複製,適合中小集群 (≤ 4 節點)。大集群改用 BackupManager。
  • McastService:組播發現成員,確保多網卡環境 address="auto" 或指定具體 IP。
  • JvmRouteBinderValve:故障轉移時重寫 Session ID 中的 jvmRoute,保證粘性路由正確。

五、應用層啟用分布式 Session

Web 應用 web.xml 必須聲明:

<web-app ... version="2.4">
    <display-name>test</display-name>
    <distributable/>  <!-- 關鍵標記 -->
</web-app>

測試頁 test.jsp:

<% session.setAttribute("time", new java.util.Date()); %>
Session ID: <%= session.getId() %><br/>
Time: <%= session.getAttribute("time") %>

六、啟動驗證順序與常見問題

  1. 啟動 tomcat1、tomcat2,檢查日誌出現 Cluster started、組播成員發現。
  2. 啟動 Apache,訪問 https://localhost/test/test.jsp 多次刷新,觀察 Session ID 後綴 . 或 . 固定(粘性生效)。
  3. 關閉一台 Tomcat,請求自動切換至另一台,Session 數據保持(複製生效)。

常見坑

  • 防火牆攔截組播/TCP 端口:需放行 45564 (UDP 組播)、4001 (TCP Receiver)、8009/9009 (AJP)。
  • jvmRoute 不一致:workers.properties 的 worker.jvm1 必須與 Tomcat jvmRoute="jvm1" 完全一致(大小寫敏感)。
  • Session 非序列化:放入 Session 的對象必須實現 Serializable,否則複製拋 NotSerializableException。
  • 時間不同步:集群節點系統時間必須 NTP 同步,否則 Session 過期判斷錯亂。

七、擴展建議

  • 水平擴展:新增 Tomcat 實例只需複製目錄、修改端口、添加 worker、更新 balance_workers。
  • 健康檢查:Nginx/Apache 上游檢查或 Tomcat Manager 應用監控。
  • Session 持久化備選:Redis + Spring Session 替代 DeltaManager,解決大集群廣播風暴、跨機房同步問題。

這套 Apache + Tomcat + mod_jk 垂直集群方案,經過生產環境驗證,穩定支撐萬級併發。掌握版本匹配、端口隔離、jvmRoute 綁定、DeltaManager 複製四大核心,即可輕鬆構建高可用 Java Web 集群。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved