標籤:jetty session 叢集 mysql mongodb
在Web開發中,Session表示HTTP伺服器與用戶端(例如瀏覽器)的“會話”,每個用戶端會有其對應的Session儲存在伺服器端,通常用來儲存和用戶端關聯的一些資訊,例如是否登入、購物車等。
Session一般情況下是儲存在伺服器記憶體中。如果伺服器重啟,Session就會丟失。另外,如果是叢集環境,一個Web應用部署在多台伺服器上,一個使用者多次請求可能會由不同的伺服器來處理,Session如果儲存在各自的伺服器上,就無法共用了。
針對這個問題,Jetty伺服器提供了用於叢集環境下的Session實現方式,即通過多台Jetty伺服器串連到同一個Session資料庫來實現Session共用。
1、配置Session儲存到關聯式資料庫(MySQL為例):
配置jetty.xml:
開啟etc/jetty.xml,在Configure元素內部加入XML片段:
<Set name="sessionIdManager"><New id="jdbcidmgr" class="org.eclipse.jetty.server.session.JDBCSessionIdManager"><Arg><Ref id="Server" /></Arg><Set name="workerName">fred</Set><Call name="setDriverInfo"><Arg>com.mysql.jdbc.Driver</Arg><Arg>jdbc:mysql://192.168.20.1:3306/jetty_session?user=root&password=123</Arg></Call><Set name="scavengeInterval">60</Set></New></Set><Call name="setAttribute"><Arg>jdbcIdMgr</Arg><Arg><Ref id="jdbcidmgr" /></Arg></Call>
修改上面XML片段中的資料庫連接的URL,如果用其他關聯式資料庫,還要修改資料庫驅動。要注意在XML中&符號要轉義成&。
配置context xml:
在jetty的webapps目錄下,建立一個XML檔案,例如test.xml,這個XML用於配置一個web應用:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd"><Configure class="org.eclipse.jetty.webapp.WebAppContext"><Set name="contextPath">/test</Set><Set name="war">D:\test.war</Set><Ref name="Server" id="Server"><Call id="jdbcIdMgr" name="getAttribute"><Arg>jdbcIdMgr</Arg></Call></Ref><Set name="sessionHandler"><New class="org.eclipse.jetty.server.session.SessionHandler"><Arg><New id="jdbcmgr" class="org.eclipse.jetty.server.session.JDBCSessionManager"><Set name="sessionIdManager"><Ref id="jdbcIdMgr" /></Set></New></Arg></New></Set></Configure>
其中,<Set name="war">D:\test.war</Set>配置web應用的war包,<Set name="contextPath">/test</Set>配置web應用的contextPath,例如http://localhost:8080/test。
啟動Jetty測試:
在啟動Jetty之前,還需要把MySQL驅動jar包放在lib/ext目錄下。此外,還要建立好資料庫,準備好war包。
一切就緒以後,就可以啟動Jetty伺服器測試Session是否已經儲存在資料庫中。
通過java -jar start.jar命令啟動Jetty伺服器,開啟瀏覽器訪問頁面。可以看到在資料庫中會產生兩個表:jettysessionids、jettysessions,分別用於儲存session id和session的資訊。如果重啟Jetty伺服器,由於Session已經持久化到資料庫中,所以Session不會丟失。
需要注意的是,由於Session儲存的是Java對象,會通過Java的序列化寫入資料庫,也就是Session中的對象必須支援序列化和還原序列化,即實現Serializable介面。
設定檔說明:
如果看不懂上面兩段XML配置的話,這裡做一個簡單的說明。
上面的這些XML實際上是Jetty的IOC設定檔,說到IOC首先會想到Spring架構,實際上Jetty的IOC和Spring的IOC解決的問題是類似的,只是XML的格式有些區別。
Jetty的IOC配置也很好理解,例如<Set name="contextPath">/test</Set>即調用setContextPath("/test"),<Call name="getAttribute"><Arg>jdbcIdMgr</Arg></Call>即調用getAttribute("jdbcIdMgr"),<New class="org.eclipse.jetty.server.session.SessionHandler"></New>即為Java執行個體化對象new SessionHandler()。
將上面的兩段XML“翻譯”成Java代碼:
import org.eclipse.jetty.server.Server;import org.eclipse.jetty.server.session.JDBCSessionIdManager;import org.eclipse.jetty.server.session.JDBCSessionManager;import org.eclipse.jetty.server.session.SessionHandler;import org.eclipse.jetty.webapp.WebAppContext;public class Main {public static void main(String[] args) throws Exception {Server server = new Server(8080);// 以下對應jetty.xml的配置JDBCSessionIdManager sessionIdManager = new JDBCSessionIdManager(server);sessionIdManager.setWorkerName("fred");sessionIdManager.setDriverInfo("com.mysql.jdbc.Driver", "jdbc:mysql://192.168.20.1:3306/jetty_session?user=root&password=123");sessionIdManager.setScavengeInterval(60);server.setAttribute("jdbcIdMgr", sessionIdManager);// 以下對應context xml的配置WebAppContext webapp = new WebAppContext();webapp.setContextPath("/test");webapp.setWar("D:\\test.war");JDBCSessionIdManager jdbcIdMgr = (JDBCSessionIdManager) server.getAttribute("jdbcIdMgr");JDBCSessionManager sessionManager = new JDBCSessionManager();sessionManager.setSessionIdManager(jdbcIdMgr);SessionHandler sessionHandler = new SessionHandler(sessionManager);webapp.setSessionHandler(sessionHandler);// 啟動伺服器server.setHandler(webapp);server.start();server.join();}}
運行Java代碼,同樣可以啟動伺服器,將Session存入資料庫,實現同樣的效果。
2、配置Session儲存到MongoDB
配置jetty.xml:
開啟etc/jetty.xml,在Configure元素內部加入XML片段:
<New id="mongodb" class="com.mongodb.MongoClient"><Arg type="java.lang.String">192.168.20.1</Arg><Arg type="int">27017</Arg><Call name="getDB"><Arg>jetty_session</Arg><Call id="sessionDocument" name="getCollection"><Arg>jetty_session_collection</Arg></Call></Call></New><Set name="sessionIdManager"><New id="mongoIdMgr" class="org.eclipse.jetty.nosql.mongodb.MongoSessionIdManager"><Arg><Ref id="Server" /></Arg><Arg><Ref id="sessionDocument" /></Arg><Set name="workerName">fred</Set><Set name="scavengePeriod">60</Set></New></Set><Call name="setAttribute"><Arg>mongoIdMgr</Arg><Arg><Ref id="mongoIdMgr" /></Arg></Call>
修改上面XML片段中的MongoDB的IP、連接埠號碼、資料庫名、Collection名。
配置context xml:
在jetty的webapps目錄下,建立一個XML檔案,例如test.xml,這個XML用於配置一個web應用:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd"> <Configure class="org.eclipse.jetty.webapp.WebAppContext"> <Set name="contextPath">/test</Set> <Set name="war">D:\test.war</Set> <Ref name="Server" id="Server"> <Call id="mongoIdMgr" name="getSessionIdManager"/> </Ref> <Set name="sessionHandler"> <New class="org.eclipse.jetty.server.session.SessionHandler"> <Arg> <New id="mongoMgr" class="org.eclipse.jetty.nosql.mongodb.MongoSessionManager"> <Set name="sessionIdManager"> <Ref id="mongoIdMgr"/> </Set> </New> </Arg> </New> </Set></Configure>
啟動Jetty測試:
測試前,首先要吧兩個jar包放在Jetty的lib/ext目錄下,一個是MongoDB的驅動包,另一個是jetty-nosql的jar包,在http://repo1.maven.org/maven2/org/eclipse/jetty/jetty-nosql/下載對應版本的jar包。此外,在MongoDB中建立好對應的資料庫。
通過java -jar start.jar命令啟動Jetty伺服器,開啟瀏覽器開啟頁面。可以看到在MongoDB中建立了配置的Collection並插入了資料:
“翻譯”成Java代碼:
將上面的兩段Jetty的IOC設定檔轉成Java代碼,直接運行可以實現同樣的功能:
import org.eclipse.jetty.nosql.mongodb.MongoSessionIdManager;import org.eclipse.jetty.nosql.mongodb.MongoSessionManager;import org.eclipse.jetty.server.Server;import org.eclipse.jetty.server.session.SessionHandler;import org.eclipse.jetty.webapp.WebAppContext;import com.mongodb.DB;import com.mongodb.DBCollection;import com.mongodb.MongoClient;public class Main {public static void main(String[] args) throws Exception {Server server = new Server(8080);// 以下對應jetty.xml的配置MongoClient mongoClient = new MongoClient("192.168.20.1", 27017);DB db = mongoClient.getDB("jetty_session");DBCollection collection = db.getCollection("jetty_session_collection");MongoSessionIdManager sessionIdManager = new MongoSessionIdManager(server, collection);sessionIdManager.setWorkerName("fred");sessionIdManager.setScavengePeriod(60);server.setAttribute("mongoIdMgr", sessionIdManager);// 以下對應context xml的配置WebAppContext webapp = new WebAppContext();webapp.setContextPath("/test");webapp.setWar("D:\\test.war");MongoSessionIdManager mongoIdMgr = (MongoSessionIdManager) server.getAttribute("mongoIdMgr");MongoSessionManager sessionManager = new MongoSessionManager();sessionManager.setSessionIdManager(mongoIdMgr);SessionHandler sessionHandler = new SessionHandler(sessionManager);webapp.setSessionHandler(sessionHandler);// 啟動伺服器server.setHandler(webapp);server.start();server.join();}}
叉叉哥 轉載請註明出處:http://blog.csdn.net/xiao__gui/article/details/43271509
Jetty叢集配置Session儲存到MySQL、MongoDB