0

目标是为当前在单个 Jetty 实例中运行的 Web 应用程序创建一个集群环境。添加集群配置时,似乎会阻止应用程序数据源池初始化。附加远程调试会话并逐步执行代码显示应用程序在启动时挂起,同时等待连接从池中释放。检查池的详细信息显示没有创建连接。c3p0 用于池化实现。当服务器在没有集群配置的情况下启动时,c3p0 会生成一条日志消息,显示它正在初始化。在配置集群的情况下启动时,看不到日志消息。让我相信应用程序数据源池永远不会初始化,因为集群数据源池正在以某种方式篡夺它。

为了获得集群行为,我将以下内容添加到 %JETTY_HOME%/etc/jetty.xml。

<New id="DSClustering" class="org.eclipse.jetty.plus.jndi.Resource">
    <Arg></Arg>
    <Arg>jdbc/DSClustering</Arg>
    <Arg>
        <New class="com.mchange.v2.c3p0.ComboPooledDataSource">            
            <Set name="driverClass">oracle.jdbc.OracleDriver</Set>
            <Set name="jdbcUrl">jdbc:oracle:thin:@xxxxx:1521:xe</Set>
            <Set name="User">xxxx</Set>
            <Set name="Password">xxxx</Set>

        </New>
    </Arg>
</New>


<Set name="sessionIdManager">
    <New id="jdbcidmgr" class="org.eclipse.jetty.server.session.JDBCSessionIdManager">
        <Arg><Ref id="Server"/></Arg>
        <Set name="workerName">jetty1</Set>
        <Set name="DatasourceName">jdbc/DSClustering</Set>
        <Set name="scavengeInterval">60</Set>
    </New>
</Set>
<Call name="setAttribute">
    <Arg>jdbcIdMgr</Arg>
    <Arg><Ref id="jdbcidmgr"/></Arg>
</Call>



并将以下内容添加到应用程序 jetty-web.xml

<Set name="sessionHandler">
    <New class="org.eclipse.jetty.server.session.SessionHandler">
        <Arg>
            <New class="org.eclipse.jetty.server.session.JDBCSessionManager">
                <Set name="idManager">
                    <Ref id="jdbcidmgr"/>
                </Set>
            </New>
        </Arg>
    </New>
</Set>



应用程序数据源池配置为 Spring bean -

<bean id="sysContextAwareDataSource" class="com.mycompany.datasource.SysContextAwareDataSource">
    <property name="targetDataSource" ref="myPoolDataSource"/>
    <property name="connectionWaitLoggingThreshold" value="1000"/>
</bean>

<bean id="myPoolDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="${jdbc.driverClassName}"/>
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <property name="user" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
    <property name="acquireIncrement" value="${jdbc.pool.acquireIncrement}"/>
    <property name="minPoolSize" value="${jdbc.pool.minPoolSize}"/>
    <property name="maxPoolSize" value="${jdbc.pool.maxPoolSize}"/>
    <property name="initialPoolSize" value="${jdbc.pool.initialPoolSize}"/>
    <property name="acquireRetryAttempts" value="${jdbc.pool.acquireRetryAttempts}"/>
    <property name="testConnectionOnCheckin" value="${jdbc.pool.testConnectionOnCheckin}"/>
    <property name="idleConnectionTestPeriod" value="${jdbc.pool.idleConnectionTestPeriod}"/>
    <property name="preferredTestQuery" value="${jdbc.pool.preferredTestQuery}"/>
    <property name="maxIdleTime" value="${jdbc.pool.maxIdleTime}"/>
    <property name="acquireRetryDelay" value="${jdbc.pool.acquireRetryDelay}"/>
    <property name="maxStatements" value="${jdbc.pool.maxStatements}"/>
    <property name="maxStatementsPerConnection" value="${jdbc.pool.maxStatementsPerConnection}"/>
</bean>


<bean id="userDAO" class="com.mycompany.dataaccess.UserDAOImpl">
    <property name="sessionFactory" ref="sessionFactory"/>
    <property name="dataSource" ref="transactionAwareDataSourceProxy"/>
</bean>

环境:jetty 8.1.9、Oracle 11g、Windows 7 Enterprise、JDK 1.6.0_38

4

1 回答 1

1

弄清楚了!这是因为我有 2 个 ojdbc-10.2.0.4.0.jar 正在被访问。为了让会话管理数据库实现工作,我在 JETTY_HOME\lib\ext 中添加了一个 ojdbc jar。这为 Jetty 服务器提供了 Oracle 类。应用程序 lib 目录中还包含一个 ojdbc jar,供应用程序使用。出现问题是因为 ojdbc jar 是“密封”的 jar。意思是,一旦从其中一个 jar 加载了一个类,尝试从另一个 jar 加载相同的类会导致引发安全异常。因此,Jetty 服务器将从 jar 的 lib/ext 版本中加载一个 Oracle 类。然后应用程序将尝试从其 ojdbc jar 加载相同的类,从而导致安全异常。花了一段时间才弄清楚,因为收到异常的 c3p0 类,默默吞下异常,然后再次尝试建立连接。这发生在另一个线程上,然后是我正在查看的线程。那是为池建立连接的线程,而我正在查看正在等待来自池的连接的线程。啊!

于 2013-02-19T21:36:12.453 回答