Spring身份验证随机停止响应并阻止应用程序访问

时间:2014-10-21 02:26:44

标签: java spring spring-mvc authentication spring-security

我们的Web应用程序存在基于Spring安全身份验证的问题。过去工作正常,而测试用户数量很少。然而,一旦我们上线并且用户数量增加,我们开始遇到弹簧认证的奇怪问题。因为我们正在使用负载均衡器并且在多个亚马逊上有应用。应用程序重新启动只能暂时解决问题。我们启用了调试日志记录,但它没有指出任何特定问题。

我们的spring security context.xml位于https://db.tt/148w2Pfh

Web.xml是https://db.tt/OqG3buPA

Spring身份验证服务https://db.tt/5v2rFNDW

尝试使用OpenID身份验证https://db.tt/tDOpnVO5

登录时的日志

尝试使用Spring安全身份验证https://db.tt/JxiwTY8a

进行登录时的日志

线程堆栈https://db.tt/F3Xtbk9R

我希望有人知道可能是什么问题。

由于

更新: Hibernate配置

public PropertiesFactoryBean hibernateProperties() {
    PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
    Properties properties = createHibernateProperties();
    propertiesFactoryBean.setProperties(properties);
    return propertiesFactoryBean;
}

private Properties createHibernateProperties() {
    Properties properties = new Properties();
    properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
    properties.setProperty("hibernate.show_sql", false);
    properties.setProperty("hibernate.max_fetch_depth", 0);
    properties.setProperty("hibernate.hbm2ddl.auto", validate);
    properties.setProperty("hibernate.jdbc.batch_size", 50);
    properties.setProperty("hibernate.connection.pool_size", 200);
    properties.setProperty("hibernate.connection.charSet", "UTF-8");
    properties.setProperty("hibernate.connection.characterEncoding", "UTF-8");
    properties.setProperty("hibernate.connection.useUnicode", true);
    properties.setProperty("hibernate.connection.autocommit", false);
    properties.setProperty("hibernate.cache.use_second_level_cache",true);
    properties.setProperty("hibernate.cache.use_query_cache", true);
    properties.setProperty("hibernate.cache.use_structured_entries", true);
    properties.setProperty("hibernate.cache.region.factory_class", "org.hibernate.cache.EhCacheRegionFactory");
    return properties;
}

@Bean (destroyMethod = "close")
public ComboPooledDataSource dataSource() {
    ComboPooledDataSource dataSource = new ComboPooledDataSource();
    try {
        dataSource.setDriverClass(Settings.getInstance().config.database.driver);
        dataSource.setJdbcUrl(Settings.getInstance().config.database.url+"?useUnicode=true&characterEncoding=UTF-8");
        dataSource.setUser(Settings.getInstance().config.database.user);
        dataSource.setPassword(Settings.getInstance().config.database.password);

        dataSource.setAcquireIncrement(10);
        dataSource.setInitialPoolSize(5);
        dataSource.setMinPoolSize(5);
        dataSource.setMaxPoolSize(50);
        dataSource.setMaxStatements(50);
        dataSource.setMaxIdleTime(3000);
        dataSource.setAutomaticTestTable("testTable");

    } catch (PropertyVetoException e) {
        logger.error(e);
    }

    return dataSource;
}

Hibernate上下文:

<!-- Adding exception translation to a template-less Hibernate DAO  -->
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<!-- Hibernate SessionFactory for the datasource -->
<bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="hibernateProperties" ref="hibernateProperties" />
    <property name="packagesToScan">
        <list>
            <value>org.prosolo.domainmodel</value>
            <value>org.prosolo.services.logging.domain</value>
            <value>org.prosolo.services.tree.settings.model</value>
        </list>
    </property>
    <property name="namingStrategy">
        <bean class="org.hibernate.cfg.ImprovedNamingStrategy" />
    </property>
</bean>

与数据源相关的Spring配置:

<!-- TRANSACTION CONFIGURATION -->

    <!-- Allowing annotation-driven transactions -->
    <tx:annotation-driven transaction-manager="transactionManager" />

    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
        <property name="dataSource" ref="dataSource" />
    </bean>

    <bean id="transactionTemplate"
        class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="transactionManager" />
    </bean>

    <bean id="taskExecutor"
        class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <property name="corePoolSize" value="5" />
        <property name="maxPoolSize" value="10" />
        <property name="WaitForTasksToCompleteOnShutdown" value="true" />
    </bean>

    <!-- Error retry advice -->
    <aop:config>
        <aop:pointcut id="transactional"
            expression="execution(* org.prosolo.services.general.impl.AbstractManagerImpl.saveEntity(..))" />
        <aop:advisor pointcut-ref="transactional" advice-ref="retryAdvice"
            order="-1" />
    </aop:config>

    <bean id="retryAdvice"
        class="org.springframework.retry.interceptor.RetryOperationsInterceptor" />

1 个答案:

答案 0 :(得分:0)

事实证明,M.Deinum在他的评论中是正确的,有连接池饥饿。我解决这个问题的方法是用Tomcat池数据源替换c3p0数据源。在这个改变之后我再也没有问题了。更新版本如下。

    @Bean (destroyMethod = "close")
public DataSource dataSource() {

    PoolProperties p = new PoolProperties();
    p.setUrl(Settings.getInstance().config.database.url+"?useUnicode=true&characterEncoding=UTF-8");
    p.setDriverClassName(Settings.getInstance().config.database.driver);
    p.setUsername(Settings.getInstance().config.database.user);
    p.setPassword(Settings.getInstance().config.database.password);
    p.setJmxEnabled(false);
    p.setTestWhileIdle(false);
    p.setTestOnBorrow(true);
    p.setValidationQuery("SELECT 1");
    p.setTestOnReturn(false);
    p.setValidationInterval(30000);
    p.setTimeBetweenEvictionRunsMillis(30000);
    p.setMaxActive(100);
    p.setInitialSize(10);
    p.setMaxWait(10000);
    p.setRemoveAbandonedTimeout(60);
    p.setMinEvictableIdleTimeMillis(30000);
    p.setMinIdle(10);
    p.setLogAbandoned(true);
    p.setRemoveAbandoned(true);
    p.setJdbcInterceptors(
            "org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"
            + "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;"
            + "org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer");
         org.apache.tomcat.jdbc.pool.DataSource ds = new org.apache.tomcat.jdbc.pool.DataSource();
         ds.setPoolProperties(p);
         return ds;
 }