前言
在 Tomcat 集群環境下,Session 共享是實現無狀態水平擴展的關鍵。利用 Tomcat Redis Session Manager 開源組件,無需修改業務代碼,僅通過配置即可將 Session 持久化至 Redis,實現多節點間 Session 透明同步。本文詳細記錄從依賴準備、配置修改到 Servlet 驗證的全過程。
一、依賴準備(三個核心 JAR)
下載並放入 $CATALINA_HOME/lib 目錄:
commons-pool2-2.2.jar —— Redis 連接池依賴
jedis-2.5.2.jar —— Redis Java 客戶端
tomcat-redis-session-manager-2.0.0.jar —— 核心 Session 管理器
提示: 版本需與 Tomcat、Redis 版本兼容,生產環境建議升級至最新穩定版(如 Jedis 4.x、commons-pool2 2.11+、Session Manager 2.5.0+)。
二、修改 context.xml 配置
編輯 $CATALINA_HOME/conf/context.xml,在 <Context> 根元素下添加:
<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
host="localhost"
port="6379"
database="0"
maxInactiveInterval="60"
/>
關鍵屬性解析:
| 屬性 | 說明 | 建議值 |
| host / port | Redis 服務地址 | 生產環境填寫集群 VIP 或 Sentinel 主節點 |
| database | Redis DB 索引 | 0(默認),建議業務隔離用單獨 DB |
| maxInactiveInterval | Session 超時時間(秒) | 1800(30 分鐘),與 web.xml session-timeout 保持一致 |
| password | Redis 認證密碼 | 若 Redis 啟用 requirepass,必須配置 |
| sessionPersistPolicy | 持久化策略 | DEFAULT(請求結束保存)、IMMEDIATE(即時)、ON_CHANGE(屬性變更時) |
三、集群部署注意事項
- 所有 Tomcat 節點配置完全一致,指向同一 Redis 實例/集群。
- 開啟 Redis 持久化(AOF/RDB),防止 Redis 重啟導致 Session 丟失。
- 配置 Redis 高可用:主從 + Sentinel 或 Redis Cluster,避免單點故障。
- Session 序列化:確保放入 Session 的對象實現
Serializable,建議使用 JDK 序列化或 Jackson/Protobuf 自定義序列化器(Session Manager 2.0+ 支持)。
- Sticky Session(可選):Nginx 層面開啟
ip_hash 或 Cookie 親和性,可減少跨節點 Session 讀寫延遲,但非強制。
四、驗證 Servlet 編寫與測試
@WebServlet(urlPatterns = "/myhttp")
public class MyHttpServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
session.setAttribute("name", "name");
session.setMaxInactiveInterval(1000); // 測試用較短超時
System.out.println("Session ID: " + session.getId());
response.getWriter().print("http");
}
}
五、驗證步驟與現象
- 啟動 Tomcat,訪問
https://localhost:8080/your-app/myhttp。
- 控制台打印 Session ID(如
5A3F2C1D-...)。
- 進入 Redis CLI:
keys *session* 或 keys *5A3F2C1D*,應看到類似 session:5A3F2C1D 的鍵。
- 啟動第二個 Tomcat 節點(端口 8081),同樣訪問 /myhttp,若能讀取到同一 Session 屬性,說明共享成功。
- 關閉第一個 Tomcat,第二個節點繼續訪問無感知,驗證故障轉移。
六、常見問題排查
- Q: Redis 連接超時 / 拒絕連接
- A: 檢查 host/port、防火牆、Redis bind 配置、密碼是否正確。
- Q: Session 屬性丟失 / ClassNotFoundException
- A: 確保所有節點 classpath 一致,放入 Session 的類實現 Serializable 且 serialVersionUID 顯式聲明。
- Q: Session ID 不一致(每次請求新建)
- A: 檢查
RedisSessionHandlerValve 是否配置在 <Context> 下,且無其他 Valve 干擾 Cookie 寫入。
七、總結
Tomcat + Redis Session 共享方案具有零代碼侵入、配置簡單、成熟穩定的優點,是中小型集群 Session 共享的首選。生產環境務必關注 Redis 高可用、序列化兼容性、超時時間一致性三大項,並做好壓測與故障演練。
- 上一篇文章: Akka 入門認知:Actor 模型核心特性、優勢場景與電信級高可用架構解析
- 下一篇文章: Java 解析網頁 JSON 數據實戰:HttpURLConnection + 官方 org.json 庫完整工具類封裝與測試
Copyright ©
程式碼之家 All Rights Reserved