首页 > 代码库 > VIRGO TOMCAT SERVER +REDIS SESSION 共享 实现

VIRGO TOMCAT SERVER +REDIS SESSION 共享 实现

项目基于OSGI规范,使用VIRGO应用服务器,

现在需要做服务器集群,需保证应用服务器无状态。


githup上有这样一个东西:tomcat redis session


地址:https://github.com/jcoleman/tomcat-redis-session-manager


virgo tomcat server 我们使用的版本是 3.0.5,它使用的tomcat版本为7.0.26

so~下载tomcat7版本的ZIP。


由于是 OSGI环境,SO~下载下来的源码是无法使用的。需要转换成OSGI bundler。


1、创建maven 普通项目

2、创建package

3、将下载的源码拷贝进来(一堆红色的错误信息,几乎都是classNotFound)

4、修改POM.xml

	<dependencies>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.tomcat</groupId>
			<artifactId>tomcat-util</artifactId>
			<version>7.0.26</version>
		</dependency>
		<dependency>
			<groupId>org.apache.tomcat</groupId>
			<artifactId>tomcat-catalina</artifactId>
			<version>7.0.26</version>
		</dependency>
		<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis-osgi</artifactId>
			<version>2.1.0</version>
		</dependency>
	</dependencies>
5、下面是重点了~配置maven bundle插件

<plugins>
			<plugin>
				<groupId>org.apache.felix.plugins</groupId>
				<artifactId>maven-osgi-plugin</artifactId>
				<extensions>true</extensions>
				<version>0.9.0-SNAPSHOT</version>
				<configuration>
					<osgiManifest>
						<bundleActivator>com.my.company.Activator</bundleActivator>
						<bundleName>Simple Bundle</bundleName>
						<bundleDescription>simple bundle</bundleDescription>
						<bundleVendor>Me</bundleVendor>
					</osgiManifest>
				</configuration>
			</plugin>
		</plugins>
貌似<osgiManifest>标签没起作用,可能是 我的 template.mf中已经写了。

6、再看下template.mf

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: com.radiadesign.catalina.session
Bundle-SymbolicName: com.radiadesign.catalina.session
Bundle-Version: 1.0.0.SNAPSHOT
Excluded-Imports: com.radiadesign.catalina.session
没啥特殊的。

7、命令行执行 mvn clean install

8、打开编译后的JAR,看下MANIFEST.MF

Manifest-Version: 1.0
Export-Package: com.radiadesign.catalina.session;version="1.0.0.SNAPSH
 OT";uses:="javax.servlet,javax.servlet.http,org.apache.catalina,org.a
 pache.catalina.connector,org.apache.catalina.session,org.apache.catal
 ina.valves,redis.clients.jedis"
Bundle-Version: 1.0.0.SNAPSHOT
Built-By: Administrator
Build-Jdk: 1.6.0_38-ea
Tool: Bundlor 1.1.1.RELEASE
Bundle-Name: com.radiadesign.catalina.session
Bundle-ManifestVersion: 2
Created-By: Apache Maven 3.0.4
Import-Package: javax.servlet,javax.servlet.http,org.apache.catalina,o
 rg.apache.catalina.connector,org.apache.catalina.session,org.apache.c
 atalina.util,org.apache.catalina.valves,org.apache.commons.pool.impl,
 org.apache.juli.logging,redis.clients.jedis
Bundle-SymbolicName: com.radiadesign.catalina.session
Archiver-Version: Plexus Archiver

自动生成了导入和导出~very good!!!!!!

9、万事俱备~只欠配置了!!!!!

又一个问题迎面而来~

tomcat中server.xml 可以在context标签中添加

<Valve className="com.radiadesign.catalina.session.RedisSessionHandlerValve" />
<Manager className="com.radiadesign.catalina.session.RedisSessionManager"
                   host="localhost" <!-- 可选,默认是"localhost" -->
                   port="6379" <!-- 可选,默认是 "6379" -->
                   database="0" <!-- 可选,默认是 "0" -->
                   maxInactiveInterval="60" <!-- 可选,默认是 "60" (单位:秒)--> />
但是在VIRGO中,官网上这样描述:

  • The <Host> child element represents a virtual host, which is an association of a network name for a server (such as www.mycompany.com) with the particular server on which Catalina is running. The servlet container unpacks Web applications into a directory hierarchy if they are deployed as WAR files.

    Note that multiple <Host> elements are not supported in Virgo Server for Apache Tomcat.


Context Configuration

Virgo Server for Apache Tomcat supports standard Apache Tomcat web application context configuration. The Apache Tomcat Configuration Reference has a section on The Context Container which describes the mechanism that is used in VTS for searching context configuration files and details the context configuration properties.

Context configuration files may be placed in the following locations, where [enginename] is the name of Tomcat‘s engine (‘Catalina‘ by default) and [hostname] names a virtual host (‘localhost‘ by default), both of which are configured in tomcat-server.xml:

  • $SERVER_HOME/configuration/context.xml provides the default context configuration file for all web applications.

  • The $SERVER_HOME/configuration/[enginename]/[hostname] directory may contain:

    • The default context configuration for all web applications of a given virtual host in the file context.xml.default.

    • Individual web applications‘ context configuration files as described in the Apache Tomcat Configuration Reference. For example, the context for a web application with context path foo may be configured infoo.xml.

Note that the following context configuration features are not supported in Virgo Server for Apache Tomcat:

  • Custom class loaders.

  • Specifying the context path. This is specified using the Web-ContextPath header in the web application‘s MANIFEST.MF file.

  • Specifying the document base directory.

这意思是说TOMCAT可以有多个HOST,但是呢VIRGO只能有一个,而且他的context块呢。需要单独建一个(默认没有)

好了,按照他说的规则,创建$SERVER_HOME/configuration/[enginename]/[hostname] 文件夹,然后创建一个文件,名字叫:context.xml.default。奇怪啊,为啥带这个后缀?

内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
--><!-- The contents of this file will be loaded for each web application --><Context antiJARLocking="true" antiResourceLocking="false">

    <!-- Default set of monitored resources -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->

    <!-- Uncomment this to enable Comet connection tacking (provides events
         on session expiration as well as webapp lifecycle) -->
    <!--
    <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
    -->
        <Valve className="com.radiadesign.catalina.session.RedisSessionHandlerValve" />
                        <Manager className="com.radiadesign.catalina.session.RedisSessionManager"
                                host="172.16.3.12" 
                                port="6379" 
                                database="0" 
                                maxInactiveInterval="60" />
</Context>

10、配置OK~接下来下菜了~~

如果是普通的TOMCAT扔到LIB里就OK了,但是呢VIRGO不行。调试了很久。

需要将 com.radiadesign.catalina.session-1.0.0-SNAPSHOT.jar、jedis-osgi-2.1.0.jar、commons-pool-1.5.5.jar放到repository/ext中。

放进去了。问题依旧。启动VIRGO时,会提示classNotFound :com.radiadesign.catalina.session.RedisSessionHandlerValve

这个时候呢。就开始纠结了。为什么?

根据OSGI的 classLoader的描述,每一个CLASS应该由父类加载,那么现在找不到他,肯定是他爹不认识他。

OK~

修改一下configuration/config.ini

最后一行添加:
osgi.debug=configuration/equinox-debug.properties(查看完classLoader一定记得注释,否则启动一次100多MB的LOG)


然后创建equinox-debug.properties,内容如下:



org.eclipse.osgi/debug=true
org.eclipse.osgi/debug/loader=true

作用:打印classLoader。一层一层的。


OK~~找到com.radiadesign.catalina.session.RedisSessionHandlerValve 的爹是org.eclipse.gemini.web.tomcat。

修改org.eclipse.gemini.web.tomcat的MAINFAST.MF文件。

在Import-package的最后一行添加:

com.radiadesign.catalina.session;version="0"


OK~


配置完成。


11、启动!!!!!!

问题又来了。

(1)首先如果session中存的是OBJECT,那么此OBJECT必须序列化。否则抛出异常。

(2)当从redis中读取session时,会提示 无法反序列化。原因是找不到OBJECT。

又来了。OBJECT又找不到爹了或者爹又找不到OBJECT了。


跟踪代码:

发现 org.apache.catalina.session.StandardSession中的1595行

 Object value = http://www.mamicode.com/stream.readObject();

此行抛出的异常,

顺藤摸瓜~~~~

参数ObjectInputStream stream的bundle是 host!!!!!!!!!!


host!!!找不到OBJECT????


确实没在host中配置import package。

将存入redis中的OBject 路径添加到 import package中。


重启服务器!


启动成功!


总算是配置OK了~存档!


           








VIRGO TOMCAT SERVER +REDIS SESSION 共享 实现