2008-11-07 72 views
10

什么是最好的方法来设置相对于您的池: -你如何设置连接池?

  1. 当你创建连接?
  2. 什么时候关闭连接,你会关闭所有连接吗?
  3. 你测试连接还是不错的。何时以及如何?
  4. 你如何找出最大连接数的好数字?
  5. 您有什么样的监控来确保游泳池的用户表现良好?你能阻止一个糟糕的代码块取出所有东西吗?
  6. 您是否编写了自己的游泳池或使用了第三方库?

我相信这是一个不可知论的问题,但对特定数据库/语言的“特性”的评论是值得欢迎的。例如,连接某些数据库比其他数据库更慢或更昂贵。

为了澄清,我不打算从头开始编写一个池,这个问题更多的是关于如何配置一个现有的库进行池化。

回答

6

我在Java中为数据库写了一个连接池,它只是一个设计模式,而不是一个公共库。现在我使用Tomcat中内置的一个。

我用了一个线程来监视池的几个方面和几个参数来控制其行为......

  1. minimumInPool =“3” ......这些前三个一经推出创建。游泳池从不允许降到三点以下。
  2. maximumIdleTimeBeforeRemoval =“60”...如果连接闲置一个小时,然后放下并创建一个新连接。空闲时间可能意味着池中只有最少三个。
  3. maximumInUseTimeBeforeRemoval =“30”...如果给定的连接已被检出超过30分钟,则可能是错误的。回想一下,并杀死连接。
  4. maximumTimeBeforeRemoval =“60”...如果超过60分钟,请将其删除。
  5. maximumUsageBeforeRemoval =“1000”...如果已经签出1000次以上,请将其删除。
  6. monitorInterval =“15”...每15分钟检查一次上述参数。

这给了我很多好几年。在野外偷看期间,我见过的最高水池有151个。通常情况下,游泳池在大量使用过程中大约有十几个,在清晨时间里至少有三个空闲。

我使用了Oracle的JDBC瘦驱动程序并连接到Oracle数据库。

1

为什么重新发明车轮?

有人已经可能解决了这个问题,而且更好。

如果您处于Java世界,您可以使用Commons DBCP

3

这是我用于最近实施的基本原理。

  1. 在连接池中有两种连接。第一个准备就绪,意味着开放但客户端不使用。第二个是积极的,意味着由客户使用。

  2. 您的连接池是否保持少量的就绪连接,最少为N,最大为M.根据客户端请求连接的最高速度,可以调整N。如果就绪连接的数量降至零,则需要更大的N.如果该数字一直很高(例如高于10),则需要较低的N.当客户端想要连接时,给它们一个(准备工作),然后立即打开一个新的工作,如果现在还没有准备好(但不要让客户等待这个完成,否则你将失去合并的优势)。这确保了总是有至少N个准备就绪的连接。如果没有人准备好当客户想要一个,他们将不得不等待,而你创建一个新的。

  3. 当客户端连接到活动连接时,如果M连接少于M个,则返回到就绪状态。否则关闭它。这可以防止您有超过M个就绪连接。

  4. 定期回收准备好的连接以防止过时的连接。如果有超过N个就绪连接,请关闭最旧的连接。否则关闭它并重新打开另一个。

这具有足够的,而不会加重服务器的连接池中的可用准备青春连接的优势。

2

我不确定你使用你的连接的上下文是什么,但我可以分享似乎为我工作的内容。

我使用SQL服务器作为我的后端,并结合使用缓存来获得更好的性能。 我的做法是保持连接打开,只有当我真的需要它并且不要连接池以便它们立即清理时,我可以在SQL Activity监视器中看到究竟什么是活动的,哪些不是。每个连接都会占用内存,因此在不需要时将其保持沉闷的咆哮是很好的。

在我回答连接开放和关闭问题之前,让我说缓存是非常重要的。从缓存中获取对象将为您节省大量时间。在我开发的一些asp.net应用程序中,当我在开发中进行缓存时,我发现我几乎无法测量延迟,而使用数据库调用可能需要15ms到45ms的任何时间来完成调用,这甚至不考虑其他延迟因素或负荷。我使用的另一种方法是用于我的数据的一种很好的对象结构,这样我只在数据库更新时才进行更新。我在我的对象上实现了一些方法o确保我尽可能少做IO。

话虽这么说,我们都知道,我们需要访问并在某些时候写信给我们的数据库,所以我遵循两个原则:

  1. 保持关闭,以节省能源的门窗。一个地方的开放连接意味着它在另一个地方不可用(或者内存和其他资源更有限)。我们已经关闭了,因为它为我们带来了更好的表现。

  2. 我可以在连接打开的情况下尽可能批量或一次性完成。这有点复杂,所以让我解释一下。

    • 我使用的一种方法是将我的连接对象向下传递给管道,以便所有对象都可以使用一个连接对象。这会导致一个连接打开和关闭,而不是10个或更多,具体取决于您的应用程序。一个很好的例子就是我们的采购模式之一,它利用SQL服务器的强大功能来收集统计数据并散列出复杂的排序模式。当您进行200K + DB查找或任何应用程序的查找时,继续打开和关闭连接是没有意义的。另一部分是,当我使用对象时,我尝试捆绑更新以减少保持连接打开的时间。因此,对插入调用做一个scope_identity让我来处理我的插入和查找唯一标识以在缓存之前添加到对象中。 回到刚开始开发asp应用程序的那一天,我实际上在页面开始加载后立即打开连接,然后关闭它。我不建议再这样做。现在每天对这些抽象和层次都有很大的好处,我会建议任何新手程序员仔细关注。

我的两分钱:

缓存您的数据!缓存你的数据!缓存你的数据!在无法缓存并缓存数据时尽可能少地访问数据库!

2

的Jakarta Commons DBCP已做了你列出的所有东西:

  • 它创建连接,根据需要和管理他们在一个池
  • ,如果他们没有被用来在一定时间内可以关闭连接的时间
  • 它可以在交出之前在连接上执行查询,如果发生错误,则连接被丢弃并创建一个新连接。连接也可以在空闲时定期测试。
  • 您可以对将要创建的连接以及准备好的最小连接数量设置限制。当然,这个限制很大程度上取决于你的应用程序。
  • 我不知道如何,但DBCP知道连接没有关闭,并关闭它,抛出一个异常,以便当你看到你的日志时知道发生了什么。
  • DBCP有一个非常有用的超时参数。如果正在使用池中的所有连接,则将等待该连接返回到该池的时间段,并且如果在达到限制时没有任何可用连接,则会出现错误。

您可以通过播放最少的连接数,要创建的最大连接数以及超时时间来优化游戏池。更长的超时时间将允许您具有较低的连接限制,而较短的超时时间可能需要较大的数量。这在很大程度上取决于您的应用程序的功能以及它如何使用连接。

2

我同意马特b,我们不应该重新发明车轮。

但是,根据thisthis问题的答案,使用Commons DBCP是有争议的。 还有更好的替代方案,如c3poproxool

或者您可以使用rdbms依赖连接池机制。