【问题标题】:Improve RESTful response time改善 RESTful 响应时间
【发布时间】:2015-08-13 21:21:04
【问题描述】:

我正在使用数据库(特别是 postgres)的 TomEE+(Apache CXF)在 Java EE 中实现 RESTful 服务。现在我注意到我的函数中花费的时间最长的是对数据库的 getConnection() 调用。

我的代码如下所示:

import java.sql.Connection;
import java.sql.SQLException;

import javax.annotation.Resource;
import javax.sql.DataSource;
import javax.ws.rs.Consumes;
import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/test")
public class TestResource {

    /* external DB resource
     * configured in the resources.xml as "testDB". Either match the
     * name or use the name parameter of the resource annotation.
     */
    @Resource private DataSource testDB;

    @Path("/hello")
    @GET
    @Produces("text/plain")
    public String test() throws SQLException
    {
        Connection conn = testDB.getConnection(); //majority of time is spent in here
    /*
      do something.(e.g. PreparedStatement ps = conn.prepareStatement(...)
    */

        conn.close();
        return "world";
    }
}

数据库在 resources.xml 中定义,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <Resource id="testDB" type="javax.sql.DataSource">
    accessToUnderlyingConnectionAllowed = false
    connectionProperties = 
    defaultAutoCommit = true
    defaultReadOnly = 
    definition = 
    ignoreDefaultValues = false
    initialSize = 0
    jdbcDriver = org.postgresql.Driver
    jdbcUrl = jdbc:postgresql://localhost/testdb
    jtaManaged = true
    maxActive = 100
    maxIdle = 20
    maxOpenPreparedStatements = 0
    maxWaitTime = 100 millisecond
    minEvictableIdleTime = 30 minutes
    minIdle = 0
    numTestsPerEvictionRun = 3
    password = password
    passwordCipher = PlainText
    poolPreparedStatements = false
    serviceId = 
    testOnBorrow = true
    testOnReturn = false
    testWhileIdle = false
    timeBetweenEvictionRuns = -1 millisecond
    userName = user
    validationQuery = SELECT 1;
    removeAbandoned = true
    removeAbandonedTimeout = 60
    logAbandoned = true

</Resource>
</resources>

那么我怎样才能减少获得数据库连接所需的时间呢?我已经在使用连接池机制了。我想到的唯一解决方案是使资源类成为单例并获得一次连接,但是当需要处理许多请求时,这似乎违反直觉。

【问题讨论】:

  • 您的观察是否针对大量请求?如果仅针对一个(尤其是第一个)请求做出分析结论,那么对于多种因素来说这有点没有意义。
  • 我重复了几次测试。时间各不相同,但总体而言,getConnection 调用总是花费大部分时间。

标签: database rest jakarta-ee cxf apache-tomee


【解决方案1】:

我通常希望与数据库的交互是该过程中最慢的部分。我想知道数据库调用增加了多少开销?这与通过 Java 代码之外的 SQL 工具进行数据库调用有何关系。

另外 - 我不确定该示例是否只是为了简洁,但我会尝试将您的解决方案分层,以便初始层处理路由和验证,而下一层处理任何业务逻辑并与数据库交互( DAO) 层。

【讨论】:

  • 我只是将所有内容放在一个函数中,例如简单性。我正在使用daos。好吧,getconnection 调用通常会消耗 1/2 甚至 2/3 的时间。所以在我为此设置的虚拟机上,整个请求通常需要 150 毫秒,而 getconnection 大约需要 90 毫秒。实际查询中的其他 60 年代。当我使用 pgadmin 之类的东西时,一个查询大约需要 40-60 毫秒。
  • 1/2 或 2/3 的时间用于数据库交互对我来说似乎并不罕见 - 数据库交互通常是解决方案中最昂贵的部分。对访问数据库的 RESTful API 的响应需要 150 毫秒,这似乎并不过分。
  • 真的吗?我的意思是我可以理解一个复杂的查询需要这么多时间,但只是从连接池中获取一个数据库连接?
  • 绝对 - 这是通配符...如果您正在处理更大的数据量和更复杂的查询,那将符合预期。如果这是对有限数据的简单查询,那似乎有点过分了。我将从把“宁静”的概念排除在等式之外。如果您使用的是基本的命令行执行类型,这需要多长时间?我的经验是,不依赖于数据库或其他 i/o 的最基本的“hello world”响应大约需要 5 毫秒。
  • 嗯,是的,但仍然如此。另外,当您从连接池中获取连接时,数据库中的数据量有什么关系?无论数据库大小如何,建立与数据库的连接不应该花费相同的时间吗?
猜你喜欢
  • 2016-08-25
  • 1970-01-01
  • 2017-02-09
  • 2010-12-16
  • 1970-01-01
  • 2021-12-13
  • 2017-03-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多