0

我讨厌提出似乎在线上有很多解决方案的问题,但我们似乎真的找不到任何有效的最佳实践解决方案来解决我们的案例,因此觉得我们别无选择。

我们正在构建一个 RESTful 服务器应用程序,其中使用间隔可能从几个小时到几个月不等。

服务器由 Jetty 托管。我们没有使用任何 ORM,但应用程序分为三层(WebService-、业务-和数据层)。数据层存在通过 Guice 框架注入的一个类。JDBC(MySQL 连接)在此类的构造函数中实例化。起初,在我们了解 Guice 默认情况下会在每个请求( ref)上创建一个新实例之前,我们遇到了太多的连接问题。为了摆脱这个问题,并且因为我们的数据层类是有状态的,我们将类注入为 Singleton。

现在我们已经预见到,当我们的 REST 应用程序有一段时间没有使用时,我们可能会遇到麻烦,因为连接会超时,并且不会实例化新的连接,因为构造函数只会被调用一次。

我们现在有多种解决方案,但我们似乎无法找出解决这个问题的最佳方法,因为它们似乎都不是那么好。对其他解决方案的任何输入或建议将不胜感激。

1.延长配置的mysql超时间隔 我们真的不想要这个,因为我们认为这真的不是最佳实践。我们当然不应该有任何泄漏的连接对象,但如果我们有,它们将填满可用连接的空闲空间。

2. 在每个方法的开头实例化一个新的连接,并在最后关闭它 据我们了解,这根本不是最佳实践,因为它会导致很多开销,应该尽可能避免吗?

3. 将注入改回“per-request”,并在每个方法结束时关闭池 这将比#2 更糟糕,因为我们不仅要实例化一个新连接,还要在每个方法上实例化一个新对象要求?

4. 在每个方法开始时检查连接的状态,如果它关闭则实例化一个新连接 一个例子是ping(example)mysql,如果它抛出异常则实例化一个新连接。这会起作用,但会产生一些开销。关于这个输入是否真的会对性能产生任何影响的任何想法?

5. 显式捕获方法中抛出的任何异常,表明连接已关闭,如果是这样 - 实例化一个新连接 这样,我们将摆脱 ping 开销,但它会使我们的代码显着复杂化,就像我们会做的那样找出一种方法来确保如果连接已经存在,这些方法将返回它们将返回的内容。

6. 使用连接池 我们不熟悉连接池,除了使用应用服务器(例如 Glassfish)。我们也想知道这是否真的能解决我们的问题?如果是这样; 关于为我们提供连接池的任何框架有什么建议吗?在这里,他们建议将 PLUS 与 Jetty 一起使用。

请问有什么不清楚的地方。我可能忘记添加一些重要信息。这对我来说更像是一个设计问题,但如果有人认为这会有所帮助,我很乐意提供任何代码。

提前致谢!

4

2 回答 2

2

连接池是要走的路。
它们有许多优点:

  1. 他们为您检查您的连接 - 这涉及超时
  2. 他们控制连接数
  3. 完成后您可以简单地关闭连接 - 您不需要保留参考

你当然应该在某种池中保持连接,事实上,如果你不咬紧牙关,你几乎肯定最终会自己写一个。当您实施连接检查以使其不会过时时,某种连接持有者使您无需每次都重新打开它们,某种异常处理代码...您明白我的意思.
我使用过dbcpboneCP,它们都非常易于使用和配置,可以为您节省数小时处理 JDBC 连接问题的挫败感。
我对 Guice 并不太熟悉,但我认为它有一些方法可以为 Object 提供您自己的工厂方法,因此您可以使用它从池中获取连接,然后进行简单调用close()当你完成将它们放回游泳池时。
如果您使用的是网络服务器,您始终可以使用interceptorfilter将连接绑定到工作线程并在处理后丢弃它们,在这种情况下,您的连接提供者只需要拉出与当前线程相关联的连接。

于 2013-02-17T22:26:46.447 回答
1

而是注入 aProvider<Connection>并让提供者从可以检测过时条目的连接池中发出连接(编辑:在您需要时)。

应该从池中丢弃未返回的连接。

于 2013-02-17T22:22:14.667 回答