Jetty集羣配置Session存儲到MySQL、MongoDB

在Web開發中,Session表示HTTP服務器與客戶端(例如瀏覽器)的「會話」,每一個客戶端會有其對應的Session保存在服務器端,一般用來保存和客戶端關聯的一些信息,例如是否登陸、購物車等。java

Session通常狀況下是保存在服務器內存中。若是服務器重啓,Session就會丟失。另外,若是是集羣環境,Web應用部署在多臺服務器上,Session若是保存在各自的服務器上,就沒法共享了。mysql

針對這個問題,Jetty服務器提供了用於集羣環境下的Session實現方式,即經過多臺Jetty服務器鏈接到同一個Session數據庫來實現Session共享。web

一、配置Session存儲到關係數據庫(MySQL爲例):

配置jetty.xml:sql

 

打開Jetty目錄下的etc/jetty.xml,在Configure元素內部加入XML片斷:mongodb

<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&amp;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中&符號要轉義成&amp;。數據庫

配置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。session

啓動Jetty測試:app

在啓動Jetty以前,還須要把MySQL驅動jar包放在Jetty的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存入數據庫,實現一樣的效果。

二、配置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();
    }
}
相關文章
相關標籤/搜索