热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用jetty+MongoDB构建session外部数据库存储方案

monbgodb简介主页http://www.mongodb.org/oschina.net介绍页http://www.oschina.net/p/mongodbMongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bjso
monbgodb简介 主页 http://www.mongodb.org/

MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
它的特点是高性能、易部署、易使用,存储数据非常方便。主要功能特性有:
面向集合存储,易存储对象类型的数据。
模式自由。
支持动态查询。
支持完全索引,包含内部对象。
支持查询。
支持复制和故障恢复。
使用高效的二进制数据存储,包括大型对象(如视频等)。
自动处理碎片,以支持云计算层次的扩展性
支持RUBY,PYTHON,JAVA,C++,PHP等多种语言。
文件存储格式为BSON(一种JSON的扩展)
可通过网络访问
所谓“面向集合”(Collenction-Orented),意思是数据被分组存储在数据集中,被称为一个集合(Collenction)。每个 集合在数据库中都有一个唯一的标识名,并且可以包含无限数目的文档。集合的概念类似关系型数据库(RDBMS)里的表(table),不同的是它不需要定 义任何模式(schema)。
模式自由(schema-free),意味着对于存储在mongodb数据库中的文件,我们不需要知道它的任何结构定义。如果需要的话,你完全可以把不同结构的文件存储在同一个数据库里。
存储在集合中的文档,被存储为键-值对的形式。键用于唯一标识一个文档,为字符串类型,而值则可以是各中复杂的文件类型。我们称这种存储形式为BSON(Binary Serialized dOcument Format)。
MongoDB服务端可运行在Linux、Windows或OS X平台,支持32位和64位应用,默认端口为27017。推荐运行在64位平台,因为MongoDB
在32位模式运行时支持的最大文件尺寸为2GB。
MongoDB把数据存储在文件中(默认路径为:/data/db),为提高效率使用内存映射文件进行管理。
在linux下先编译安装下吧。下载mongodb源码 http://downloads.mongodb.org/src/mongodb-src-r2.4.4.tar.gz
也可以下载二进制的,有各种平台的。80多MB,挺大的。建议下载二进制,因为源码编译 虽然眼前一亮,学到点新东西,但是编译体积太大了。我来研究下源码编译mongodb吧。
解压mongodb-src-r2.4.4.tar.gz后,进入目录,发现没有configure或者Makefile,一时木了,不知所戳,姑搜索 编译mongodb ,原来是这样啊:

第一步  安装SCons
Scons是一个Python写的自动化构建工具,比传统的GNU make更加简便、可靠以及高效。
到http://sourceforge.net/projects/scons/files/scons/下载源码压缩包,解压之后按照如下步骤进行安装:
python setup.py install
Centos下也可以yum install scons

第二步 编译Mongodb
进入mongodb源码目录
scons all scons ?prefix=/usr/local/mongodb install -j 8
如果想要头文件和lib包,执行
scons ?prefix=/usr/local/mongodb ?full install -j 8
默认编译完毕要花很久的时间,而且编译体积太大了。查看下源码目录
[root@xen1 mongodb-src-r2.4.4]# du -sh * #去掉小于1M的了
15M     authTest
252M    bsondump
8.3G    build
4.0M    buildscripts
16M     clientTest
15M     firstExample6.2M    httpClientTest
5.5M    jstests
114M    mongo
252M    mongobridge
254M    mongod
253M    mongodump
252M    mongoexport
253M    mongofiles
253M    mongoimport
252M    mongooplog
252M    mongoperf
253M    mongorestore
182M    mongos
253M    mongostat
252M    mongotop
253M    perftest
15M     rsExample
15M     secondExample
71M     src
361M    test
15M     tutorial
15M     whereExample
xxK     ...
[root@xen1 mongodb-src-r2.4.4]# pwd
/root/mongodb-src-r2.4.4
[root@xen1 mongodb-src-r2.4.4]# du -sh .
13G     .
[root@xen1 mongodb-src-r2.4.4]#ll
总用量 4141620
-rw-rw-r--  1 root root     11358 6月   3 04:58 APACHE-2.0.txt
-rwxr-xr-x  1 root root  15207135 6月  20 12:28 authTest
-rwxr-xr-x  1 root root    543371 6月  20 12:29 bsondemo
-rwxr-xr-x  1 root root 264008056 6月  20 12:19 bsondump
drwxr-xr-x  3 root root      4096 6月  20 13:16 build
drwxrwxr-x  4 root root      4096 6月  20 11:27 buildscripts
-rwxr-xr-x  1 root root  15821236 6月  20 12:28 clientTest
-rw-rw-r--  1 root root      2948 6月   3 04:58 CONTRIBUTING.rst
drwxrwxr-x  2 root root      4096 6月   3 04:58 debian
drwxrwxr-x  3 root root      4096 6月   3 04:58 distsrc
drwxrwxr-x  2 root root      4096 6月   3 04:58 docs
-rw-rw-r--  1 root root     10808 6月   3 04:58 doxygenConfig
-rwxr-xr-x  1 root root  15211226 6月  20 12:28 firstExample
-rw-rw-r--  1 root root     34520 6月   3 04:58 GNU-AGPL-3.0.txt
-rwxr-xr-x  1 root root   6440685 6月  20 12:28 httpClientTest
drwxrwxr-x 22 root root     24576 6月   3 04:58 jstests
-rwxr-xr-x  1 root root 119133125 6月  20 11:42 mongo
-rw-rw-r--  1 root root       191 6月   3 04:58 mongo_astyle
-rwxr-xr-x  1 root root 264063672 6月  20 12:25 mongobridge
-rwxr-xr-x  1 root root 265599076 6月  20 12:01 mongod
-rwxr-xr-x  1 root root 264731994 6月  20 12:06 mongodump
-rwxr-xr-x  1 root root 264216054 6月  20 12:09 mongoexport
-rwxr-xr-x  1 root root 264568847 6月  20 12:18 mongofiles
-rwxr-xr-x  1 root root 264465437 6月  20 12:11 mongoimport
-rwxr-xr-x  1 root root 264239179 6月  20 12:16 mongooplog
-rwxr-xr-x  1 root root 263957415 6月  20 12:21 mongoperf
-rwxr-xr-x  1 root root 264674145 6月  20 12:07 mongorestore
-rwxr-xr-x  1 root root 190460179 6月  20 12:04 mongos
-rwxr-xr-x  1 root root 264779175 6月  20 12:12 mongostat
-rwxr-xr-x  1 root root 264125459 6月  20 12:14 mongotop
-rwxr-xr-x  1 root root 264976307 6月  20 12:23 perftest
-rwxrwxr-x  1 root root      1769 6月   3 04:58 README
drwxrwxr-x  2 root root      4096 6月   3 04:58 rpm
-rwxr-xr-x  1 root root  15304506 6月  20 12:28 rsExample
-rw-rw-r--  1 root root      2251 6月   3 04:58 SConscript.buildinfo
-rw-rw-r--  1 root root      6178 6月   3 04:58 SConscript.smoke
-rw-rw-r--  1 root root     38380 6月   3 04:58 SConstruct
-rwxr-xr-x  1 root root  15199859 6月  20 12:29 secondExample
drwxrwxr-x  3 root root      4096 6月  20 11:27 site_scons
drwxrwxr-x  4 root root      4096 6月   3 04:58 src
-rwxr-xr-x  1 root root 378493910 6月  20 12:41 test
-rwxr-xr-x  1 root root  15299544 6月  20 12:29 tutorial
-rw-rw-r--  1 root root       254 6月   3 04:58 valgrind.suppressions
-rwxr-xr-x  1 root root  15257921 6月  20 12:29 whereExample
-rw-rw-r--  1 root root       448 6月   3 04:58 win2008plus.props
[root@xen1 mongodb-src-r2.4.4]#
View Code scons后面跟的参数 -j 8 是8线程同时编译,加快编译速度,其他参数未知,从其他地方引用过来的。好像 直接scons -j 8  应该也可以编译。但是编译出来的mongod 文件太大了,肯定有优化的参数,暂时不知道。查看了mongodb的文档,也没看到如何编译,都是二进制安装的。我无语,哪就不研究源码编译了。
mongodb官方的 yum 源,下载到 yum.repos.d/10gen.repo ,以后就可以安装二进制包了。
# /etc/yum.repos.d/10gen.repo
[10gen]
name=10gen Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64
#baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/i686
gpgcheck=0
enabled=1
yum install mongo-10gen mongo-10gen-server 就可以安装最新版的 mongodb 了。包括init.d服务启动文件和配置文件。
启动文件mongod复制过来 参考一下。
#!/bin/bash
# mongod - Startup script for mongod
# chkconfig: 35 85 15
# description: Mongo is a scalable, document-oriented database.
# processname: mongod
# config: /etc/mongod.conf
# pidfile: /var/run/mongo/mongod.pid
. /etc/rc.d/init.d/functions
# things from mongod.conf get there by mongod reading it
# NOTE: if you change any OPTIONS here, you get what you pay for:
# this script assumes all options are in the config file.
COnFIGFILE="/etc/mongod.conf"
OPTIOnS=" -f $CONFIGFILE"
SYSCOnFIG="/etc/sysconfig/mongod"
# FIXME: 1.9.x has a --shutdown flag that parses the config file and
# shuts down the correct running pid, but that's unavailable in 1.8
# for now.  This can go away when this script stops supporting 1.8.
DBPATH=`awk -F= '/^dbpath=/{print $2}' "$CONFIGFILE"`
PIDFILE=`awk -F= '/^dbpath\s=\s/{print $2}' "$CONFIGFILE"`
mOngod=${MONGOD-/usr/bin/mongod}
MONGO_USER=mongod
MONGO_GROUP=mongod
if [ -f "$SYSCONFIG" ]; then
    . "$SYSCONFIG"
fi
# Handle NUMA access to CPUs (SERVER-3574)
# This verifies the existence of numactl as well as testing that the command works
NUMACTL_ARGS="--interleave=all"
if which numactl >/dev/null 2>/dev/null && numactl $NUMACTL_ARGS ls / >/dev/null 2>/dev/null
then
    NUMACTL="numactl $NUMACTL_ARGS"
else
    NUMACTL=""
fi
start()
{
  echo -n $"Starting mongod: "
  daemon --user "$MONGO_USER" $NUMACTL $mongod $OPTIONS
  RETVAL=$?
  echo
  [ $RETVAL -eq 0 ] && touch /var/lock/subsys/mongod
}
stop()
{
  echo -n $"Stopping mongod: "
  killproc -p "$PIDFILE" -d 300 /usr/bin/mongod
  RETVAL=$?
  echo
  [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/mongod
}
restart () {
    stop
    start
}
ulimit -n 12000
RETVAL=0
case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  restart|reload|force-reload)
    restart
    ;;
  condrestart)
    [ -f /var/lock/subsys/mongod ] && restart || :
    ;;
  status)
    status $mongod
    RETVAL=$?
    ;;
  *)
    echo "Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart}"
    RETVAL=1
esac
exit $RETVAL
View Code 还有配置文件/etc/mongod.conf
# mongo.conf
#where to log
logpath=/var/log/mongo/mongod.log
logappend=true
# fork and run in background
fork = true
#port = 27017
dbpath=/var/lib/mongo
# location of pidfile
pidfilepath = /var/run/mongodb/mongod.pid
# Disables write-ahead journaling
# nojournal = true
# Enables periodic logging of CPU utilization and I/O wait
#cpu = true
# Turn on/off security.  Off is currently the default
#noauth = true
#auth = true
# Verbose logging output.
#verbose = true
# Inspect all client data for validity on receipt (useful for
# developing drivers)
#objcheck = true
# Enable db quota management
#quota = true
# Set oplogging level where n is
#   0=off (default)
#   1=W
#   2=R
#   3=both
#   7=W+some reads
#diaglog = 0
# Ignore query hints
#nohints = true
# Disable the HTTP interface (Defaults to localhost:27018).
#nohttpinterface = true
# Turns off server-side scripting.  This will result in greatly limited
# functionality
#noscripting = true
# Turns off table scans.  Any query that would do a table scan fails.
#notablescan = true
# Disable data file preallocation.
#noprealloc = true
# Specify .ns file size for new databases.
# nssize = 
# Accout token for Mongo monitoring server.
#mms-token = 
# Server name for Mongo monitoring server.
#mms-name = 
# Ping interval for Mongo monitoring server.
#mms-interval = 
# Replication Options
# in replicated mongo databases, specify here whether this is a slave or master
#slave = true
#source = master.example.com
# Slave only: specify a single database to replicate
#only = master.example.com
# or
#master = true
#source = slave.example.com
View Code service mongod start
service mongod status
就开启了服务了。
打开浏览器 输入 http://IP:27017 显示:
You are trying to access MongoDB on the native driver port. For http diagnostic access, add 1000 to the port number
 按照提示,将端口号增加1000 ,打开 http://IP:28017 将会显示一个mongod服务的概述吧。此功能 或许应该关闭。
测试Insert update delete select 操作
输入mongo 即可打开客户端,连接默认端口 默认本机的mongodb的服务。
输入
db.test.save( { a: 1 } )
db.test.find()
 第二阶段 配置jetty与mongodb之间的连接
按照官方文档,http://wiki.eclipse.org/Jetty/Tutorial/MongoDB_Session_Clustering 
我把一些配置 加入到jetty.xml中,重启jetty 报错。大概是 org.eclipse.jetty.nosql.mongodb.* 不知道在哪里,后来我发现:
我发现eclipse的jetty网页 是十分让人恶心的,至少是我。
在 http://download.eclipse.org/jetty/stable-8/apidocs/ 明明有nosql.mongodb 的javadoc http://download.eclipse.org/jetty/stable-7/apidocs/org/eclipse/jetty/nosql/mongodb/MongoSessionManager.html
但是我从 http://download.eclipse.org/jetty/ 下载的stable-8 里面的javadoc中却没有这块内容,为什么神奇的消失了?后来看到老外的一个文章 
http://www.jamesward.com/2011/11/30/using-mongodb-for-a-java-web-apps-httpsession
使用maven来下载jetty插件,然后再%HOME%\.m2\repository\org\eclipse\jetty 出现了 jetty-nosql jetty-nosql-8.0.3.v20111011.jar ,终于看到了这个包,里面有nosql\mongodb 了。我就奇怪了,eclipse的jetty网站下载jetty 为什么没有jetty-nosql呢?如果是第三方,哪为什么在apidoc里面还有nosql的javadoc呢?
恶心。恶心eclipse。
 好吧,继续配置jetty与mongodb:
jetty-nosql 下载:http://repo1.maven.org/maven2/org/eclipse/jetty/jetty-nosql/8.1.11.v20130520/
还有一个mongodb-java-driver:http://repo1.maven.org/maven2/org/mongodb/mongo-java-driver/2.7.3/
 具体 有关mongodb 的java驱动 看: http://docs.mongodb.org/ecosystem/tutorial/getting-started-with-java-driver/
然后我开始了另一端苦逼的研究,把这俩jar文件放到哪里呢?我放到/root/下,然后设置CLASSPATH,添加了这两个jar的绝对路径【后来证明我的做法不被支持,继续看吧】,修改$JETTY_HOME/start.ini 加入了一个  配置选项:
然后 touch etc/jetty-nosql.xml ,里面内容如下: 




        
                
                        
                

                fred
                60
        


        mongoIdMgr
        
                
        



      
        
          
            
              
                localhost

                27017

              
            
          
          
         
      
      
        HttpSessions
        
          sessions
        
      
      
      
 
    
      
        
          
        

        
          
        

        fred
        60
      
    

这个看起来是xml,其实确实是xml,但是里面的内容不是随便搞的,其会映射为一些java代码的。随便写点内容,jetty就会报异常的,我service jetty restart 报错为:
[root@localhost jetty]# service  jetty restart
Stopping Jetty: OK
Starting Jetty: 2013-06-22 11:35:20.287:WARN:oejx.XmlConfiguration:Config error at |?|???|??fred60| java.lang.ClassNotFoundException: org.eclipse.jetty.nosql.mongodb.MongoSessionIdManager
java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
        at org.eclipse.jetty.start.Main.invokeMain(Main.java:473)
        at org.eclipse.jetty.start.Main.start(Main.java:615)
        at org.eclipse.jetty.start.Main.main(Main.java:96)
Caused by: java.lang.ClassNotFoundException: org.eclipse.jetty.nosql.mongodb.MongoSessionIdManager
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
        at org.eclipse.jetty.util.Loader.loadClass(Loader.java:100)
        at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.nodeClass(XmlConfiguration.java:354)
        at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.newObj(XmlConfiguration.java:754)
        at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.itemValue(XmlConfiguration.java:1126)
        at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.value(XmlConfiguration.java:1029)
        at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.set(XmlConfiguration.java:422)
        at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.configure(XmlConfiguration.java:384)
        at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.configure(XmlConfiguration.java:343)
        at org.eclipse.jetty.xml.XmlConfiguration.configure(XmlConfiguration.java:296)
        at org.eclipse.jetty.xml.XmlConfiguration$1.run(XmlConfiguration.java:1247)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1182)
        ... 7 more
Usage: java -jar start.jar [options] [properties] [configs]
       java -jar start.jar --help  # for more information
FAILED Sat Jun 22 11:35:23 CST 2013
[root@localhost jetty]#
没有找到类,哪就是我设置的jar的classpath居然没用,对于一般的java程序是管用的。然后研究,java -jar start.jar --help 有--list-options和--list-config 其都是在start.jar里面一个start.config的文件里面的配置,查看了下,里面的OPTIONS 其实就是指定的一些jar包,然后配合jetty-XXX.xml,就可以实现这一方面的功能了,比如jetty-ajp-VERSION.jar和jetty-ajp.xml,我在start.ini里面加入OPTIONS ajp,和etc/jetty-ajp.xml 才有了ajp的功能。
那么我的mongodb-java-driver.jar和jetty-nosql.jar放到哪里呢?难道要我修改start.jar里面的配置文件再放入,jetty,java,你有必要这么麻烦么?配置文件,你有必要弄的这样个性化,不具备普及型么?后来才发现,原来 jetty额外的包(jar文件)应该放到jetty目录的/lib/ext目录下,而不是/lib目录下。
你妹的,真方便,把两个jar放入lib/ext 再开启服务,果然OK,找到了这些个jar了,搜索jar本来是jvm干的事情,用classpath就可以做到,你非要逆天而行,自己搜索jar,还不接受jvm搜索jar的classpath路径,好吧,我认输,java有太多的这样的事情了。
测试 session是否存储到mongodb上,以及mongodb的分布式配置
TODO。。。

MongoDB与sql语句对照表
SQL Statement  Mongo Query Language Statement 
CREATE TABLE USERS (a Number, b Number)
implicit; can be done explicitly
INSERT INTO USERS VALUES(1,1)
db.users.insert({a:1,b:1})
SELECT a,b FROM users
db.users.find({}, {a:1,b:1})
SELECT * FROM users
db.users.find()
SELECT * FROM users WHERE age=33
db.users.find({age:33})
SELECT a,b FROM users WHERE age=33
db.users.find({age:33}, {a:1,b:1})
SELECT * FROM users WHERE age=33 ORDER BY name
db.users.find({age:33}).sort({name:1})
SELECT * FROM users WHERE age>33
db.users.find({'age':{$gt:33}})})
SELECT * FROM users WHERE age<33
db.users.find({'age':{$lt:33}})})
SELECT * FROM users WHERE name LIKE "%Joe%"
db.users.find({name:/Joe/})
SELECT * FROM users WHERE name LIKE "Joe%"
db.users.find({name:/^Joe/})
SELECT * FROM users WHERE age>33 AND age<=40
db.users.find({'age':{$gt:33,$lte:40}})})
SELECT * FROM users ORDER BY name DESC
db.users.find().sort({name:-1})
CREATE INDEX idx_name ON users(name)
db.users.ensureIndex({name:1})
CREATE INDEX idx_name ON users(name,ts DESC)
db.users.ensureIndex({name:1,ts:-1})
SELECT * FROM users WHERE a=1 and b='q'
db.users.find({a:1,b:'q'})
SELECT * FROM users LIMIT 10 SKIP 20
db.users.find().limit(10).skip(20)
SELECT * FROM users WHERE a=1 or b=2
db.users.find( { $or : [ { a : 1 } , { b : 2 } ] } )
SELECT * FROM users LIMIT 1
db.users.findOne()
EXPLAIN SELECT * FROM users WHERE z=3
db.users.find({z:3}).explain()
SELECT DISTINCT last_name FROM users
db.users.distinct('last_name')
SELECT COUNT(*y) FROM users
db.users.count()
SELECT COUNT(*y) FROM users where AGE > 30
db.users.find({age: {'$gt': 30}}).count()
SELECT COUNT(AGE) from users
db.users.find({age: {'$exists': true}}).count()
UPDATE users SET a=1 WHERE b='q'
db.users.update({b:'q'}, {$set:{a:1}}, false, true)
UPDATE users SET a=a+2 WHERE b='q'
db.users.update({b:'q'}, {$inc:{a:2}}, false, true)
DELETE FROM users WHERE z="abc"
db.users.remove({z:'abc'});

推荐阅读
author-avatar
哈行小DWW_421
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有