你如何设置连接池?

时间:2008-11-07 03:49:20

标签: rdbms connection-pooling

设置游泳池的最佳方法是: -

  1. 什么时候创建连接?
  2. 什么时候关闭连接,你会关闭所有连接吗?
  3. 你测试连接是否仍然良好。何时以及如何?
  4. 如何确定最大连接数的良好数字?
  5. 您有什么样的监控来确保池的用户表现良好?你可以阻止一段不好的代码取出所有东西吗?
  6. 您是否已编写自己的池,或使用过第三方库?
  7. 我认为这是一个不可知的问题,但欢迎对特定数据库/语言的“功能”发表评论。例如,在某些数据库上连接可能比其他数据库更慢或更昂贵。

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

6 个答案:

答案 0 :(得分: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分钟检查一次上述参数。
  7. 这对我来说非常好用了几年。我见过的最高的游泳池是疯狂偷看的151个连接。通常情况下,在大量使用期间,游泳池大约有十几个,并且在凌晨时分闲置至最少三个。

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

答案 1 :(得分:3)

以下是我最近实施的基本原理。

  1. 您的连接池中有两种连接。第一个是准备好的,意思是开放但客户没有使用。第二个是活动的,意味着客户使用。

  2. 让您的连接池保持少量就绪连接,最小N和最大M. N可以根据客户端请求连接的峰值速度进行调整。如果就绪连接的数量永远减少到零,则需要更大的N.如果数字一直很高(例如大于10),则需要更低的N.

  3. 当客户想要连接时,给他们一个准备好的连接(使其处于活动状态),然后立即打开一个新的,如果现在已经准备好了N(但不要让客户等待这个完成,否则你将失去合并的优势)。这可确保始终至少有N个就绪连接。如果在客户需要时没有准备好,他们将不得不在你创建一个新的时候等待。

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

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

  6. 这样做的好处是可以在连接池中提供足够的就绪年轻连接,而不会使服务器过载。

答案 2 :(得分:2)

我不确定您使用连接的上下文,但我可以分享对我有用的内容。

我使用SQL服务器作为我的后端,并使用缓存的组合来获得更好的性能。 我的做法是只在我确实需要它时才保持连接打开,并且不要将连接池连接起来,以便它们立即清理,我可以在SQL Activity监视器中看到确切的活动内容和不活动内容。每个连接占用内存,因此在不需要它时保持它是一种沉闷的咆哮是很好的。

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

话虽如此,我们都知道我们需要在某个时刻访问和写入我们的数据库,所以我遵循两个原则:

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

  2. 我在打开连接时尽可能多地批量处理或立即执行此操作。这有点复杂,所以让我解释一下。

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

    缓存您的数据!缓存您的数据!缓存您的数据!当您无法缓存然后缓存数据时,请尽可能少地访问数据库!

答案 3 :(得分:2)

Jakarta Commons DBCP已经完成了你列出的所有内容:

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

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

答案 4 :(得分:2)

我同意亚光b,我们不应该重新发明轮子。

然而,根据thisthis问题的答案,使用Commons DBCP是有争议的。 这里提到了更好的替代方案,例如c3poproxool

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

答案 5 :(得分:1)

为什么重新发明轮子?

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

如果您在Java世界中,可以使用Commons DBCP