简体   繁体   English

使用JNDI的速度明显比persistence.xml(Jetty 9 / Hibernate)中的显式连接慢。

[英]Using JNDI is significantly slower than explicit connection in persistence.xml (Jetty 9/Hibernate)

On a standalone Jetty 9.4 server I am deploying an app which utilizes hibernate JPA. 在独立的Jetty 9.4服务器上,我正在部署一个使用休眠JPA的应用程序。 I have observed the following strange behaviour (might not be strange, I am sure I am just missing some concept) 我观察到以下奇怪行为(可能并不奇怪,我敢肯定我只是缺少一些概念)

If I explicitly declare db connection properties in the applications persistence xml, I get 15-20 ms responses for a service that reads some dummy data from the db. 如果我在应用程序持久性xml中显式声明数据库连接属性,则对于从数据库读取一些虚拟数据的服务,我将获得15-20毫秒的响应。 It is like 300ms for the first try, then the pooling kicks in. 第一次尝试大约是300毫秒,然后开始合并。

If I use a JNDI datasource and reference it in the persistence xml, I get 1 second initial response time, then it is between 300-400 ms on the same local environment. 如果我使用JNDI数据源并在持久性xml中引用它,那么我将获得1秒的初始响应时间,那么在同一本地环境下,它的响应时间为300-400毫秒。

My question would be that is that a normal behaviour? 我的问题是那是正常的行为吗? Is JNDI always that slow or it may just be some bad configuration? JNDI总是那么慢还是它可能是一些错误的配置? Is it the jetty implementation that is slow? 码头实施缓慢吗?

ps I have tried to declare a PoolDataSource as the JNDI resource, but persistence.xml does not accept it. ps我试图将PoolDataSource声明为JNDI资源,但是persistence.xml不接受它。

Thanks in advance for the answers. 预先感谢您的回答。

persistence.xml persistence.xml

    <persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0">
    <persistence-unit name="flapweb">
        <non-jta-data-source>java:comp/env/jdbc/mydatasource</non-jta-data-source>
        <properties>
            <!--property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5433/postgres" />
            <property name="javax.persistence.jdbc.user" value="user" />
            <property name="javax.persistence.jdbc.password" value="password" /-->

            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/> <!-- DB Dialect -->
            <property name="hibernate.hbm2ddl.auto" value="update" /> <!-- create / create-drop / update -->

            <property name="hibernate.show_sql" value="true" /> <!-- Show SQL in console -->
            <property name="hibernate.format_sql" value="true" /> <!-- Show SQL formatted -->

            <property name="hibernate.c3p0.min_size" value="5" />
            <property name="hibernate.c3p0.max_size" value="20" />
            <property name="hibernate.c3p0.timeout" value="500" />
            <property name="hibernate.c3p0.max_statements" value="50" />
            <property name="hibernate.c3p0.idle_test_period" value="2000" />
        </properties>
    </persistence-unit>
</persistence>

Datasource JNDI declaration 数据源JNDI声明

    <?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">


<Configure id="Server" class="org.eclipse.jetty.server.Server">

    <New id="mydatasource" class="org.eclipse.jetty.plus.jndi.Resource">
        <Arg></Arg>
        <Arg>jdbc/mydatasource</Arg>
        <Arg>
            <New class="org.postgresql.ds.PGSimpleDataSource">
                <Set name="databaseName">postgres</Set>
                <Set name="serverName">localhost</Set>
                <Set name="portNumber">5433</Set>
                <Set name="user">user</Set>
                <Set name="password">password</Set>
            </New>
        </Arg>
    </New>

</Configure>

Okay, after many attempts I have found the solution. 好的,经过多次尝试,我找到了解决方案。

Short anwser, I have to use a c3po DataSource as a JNDI resource, so the retrieved connection will always come from a pool. 简短的回答,我必须使用c3po数据源作为JNDI资源,因此检索到的连接将始终来自于池。 I also do not need any hibernate.c3p0.* settings. 我也不需要任何hibernate.c3p0。*设置。 Example: https://www.eclipse.org/jetty/documentation/9.4.x/jndi-datasource-examples.html#c3p0-datasource . 例如: https : //www.eclipse.org/jetty/documentation/9.4.x/jndi-datasource-examples.html#c3p0-datasource c3po and postgres jars need to be at jetty classpath. c3po和postgres罐子必须位于码头类路径下。

The reason why my previous solution did not work is because it seems that hibernate does not apply any c3po/connection pool settings to JNDI retrieved datasources, because it assumes that it is managed by the application server / servlet container. 我以前的解决方案不起作用的原因是因为hibernate似乎没有将任何c3po /连接池设置应用于JNDI检索到的数据源,因为它假定它是由应用程序服务器/ servlet容器管理的。

I also could not use PGConnectionPoolDataSource because that class does not implement the javax.sql.DataSource hence it cannot be referenced in persistence xml. 我也不能使用PGConnectionPoolDataSource,因为该类未实现javax.sql.DataSource,因此无法在持久性xml中引用它。

I hope this will help someone in the future. 我希望这会在将来对某人有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM