在Web开发中,Session表示HTTP服务器与客户端(例如浏览器)的“会话”,每个客户端会有其对应的Session保存在服务器端,通常用来保存和客户端关联的一些信息,例如是否登录、购物车等。

Session一般情况下是保存在服务器内存中。如果服务器重启,Session就会丢失。另外,如果是集群环境,Web应用部署在多台服务器上,Session如果保存在各自的服务器上,就无法共享了。

针对这个问题,Jetty服务器提供了用于集群环境下的Session实现方式,即通过多台Jetty服务器连接到同一个Session数据库来实现Session共享。

1、配置Session存储到关系数据库(MySQL为例):

配置jetty.xml:

打开Jetty目录下的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&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。

启动Jetty测试:

在启动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存入数据库,实现同样的效果。

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();
}
}

Jetty集群配置Session存储到MySQL、MongoDB的更多相关文章

  1. Jetty容器集群配置Session存储到MySQL、MongoDB

    在Web开发中,Session表示HTTP服务器与客户端(例如浏览器)的"会话",每个客户端会有其对应的Session保存在服务器端,通常用来保存和客户端关联的一些信息,例如是否登 ...

  2. 基于apache的tomcat负载均衡和集群配置session共享

    接上面的话题接着继续完善.为什么没接到上篇呢?原因很简单太长的文章不爱看!就像有人写了上千行的方法一样,不是逼得没办法谁爱看谁看,反正我不看. 期间我没有一次配置成功,从失败的开始说起, 1.准备ja ...

  3. harbor高可用集群配置

    目录 说明 双主复制 主从同步 双主复制说明 多harbor实例共享后端存储 方案说明 环境说明 配置说明 安装redis和mysql 导入registry数据库 配置harbor 挂载nfs目录 修 ...

  4. Redis存储Tomcat集群的Session

    Redis存储Tomcat集群的Session 如何 做到把新开发的代码推送到到生产系统中部署,生产系统要能够零宕机.对使用用户零影响. 设想 是使用集群来搞定,通过通知负载均衡Nginx,取下集群中 ...

  5. Nginx+Memcached+Tomcat集群配置实践(Sticky Session)

    准备工作 创建一个简单的web应用,名为session.其中有两个页面,分别如下所示: 页面login.jsp <%@ page language="java" conten ...

  6. Nginx集群配置与redis的session共享策略

    一.什么是Nginx? Nginx (engine x) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器.Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Ramb ...

  7. MySQL Cluster 7.3.5 集群配置实例(入门篇)

    一.环境说明: CentOS6.3(32位) + MySQL Cluster 7.3.5,规划5台机器,资料如下: 节点分布情况: MGM:192.168.137. NDBD1:192.168.137 ...

  8. MySQL Cluster 7.3.5 集群配置参数优化(优化篇)

    按照前面的教程:MySQL Cluster 7.3.5 集群配置实例(入门篇),可快速搭建起基础版的MySQL Cluster集群,但是在生成环境中,还是有很多问题的,即配置参数需要优化下, 当前生产 ...

  9. Openstack的HA解决方案【mysql集群配置】

    使用mysql的galera做多主集群配置,galera的集群优势网络上面有对比,这里不在叙述. 1. 新建3台虚拟机(centos6.5) node1:172.17.44.163 node2:172 ...

随机推荐

  1. Matlab 运行C程序出现的编译出错问题

    2016-03-18 17:18:34 最近在运行一些公开的Matlab代码包时,比如LibSVM.crfChain等,遇到了需要在Matlab环境下编译C程序的问题,对于我所遇到的问题,给出以下解决 ...

  2. 有关google的小问题

    从本周的开始,突然发现自己的浏览器打不开google了,我的默认浏览器是qq的,不过使用的也是google搜索.刚开始我以为是浏览器中毒了,就重新下了一个,结果还是同样的情况,而且我使用搜狗或者百度的 ...

  3. map() 函数

    map()函数 map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回. 例如,对于li ...

  4. ansible 自动化(1)

    安装篇: yum安装 1.安装第三方epel源 centos 6的epel rpm -ivh http://mirrors.sohu.com/fedora-epel/6/x86_64/epel-rel ...

  5. Online Judge中基本的输入输出

    一.利用c语言处理输入和输出 1.输入: 在C语言中输入中stdin指针表示标准的输入,scanf默认读取的就是stdin指向的输入,在acm中我们可能需要不断的测试,最好将stdin重定向到某一个文 ...

  6. linux-10 基本命令之查看内存使用情况- free,history,who,last

    free 命令 显示当前系统中内存的使用量情况  格式如下:free[-m/-g] 以m为单位显示当前内存的使用情况 [root@localhost /]# free -m 内存总量 已用量 可用量 ...

  7. winform 子报表

    public void BindReport(string _invno,string _type)         {             if (!Is_Has_Express_No(_inv ...

  8. 移动开发发展方向-----Hybird混合开发3大方案

    移动开发发展方向-----Hybird混合开发3大方案

  9. objective-c(代码块)

    objective-c代码块(block)对写惯C语言的人非常熟悉,就类似一个函数指针,指向一个代码段的首地址: 给出简单例子如下: int main(int argc, const char * a ...

  10. Ubuntu Desktop安装及桌面美化(修复图片)

    Ubuntu Desktop安装及桌面美化 1   开篇概述 本 系统的文章主要是讲互联网方向的开发主题.根据目前主流互联网公司的技术架构,Linux是必不可少的.对于一直习惯于在Windows下工作 ...