Haskell数据库连接

时间:2016-08-13 21:43:40

标签: mongodb haskell scotty

请查看这个scotty应用程序(它直接来自this old answer from 2014):

import Web.Scotty
import Database.MongoDB
import qualified Data.Text.Lazy as T
import Control.Monad.IO.Class

runQuery :: Pipe -> Query -> IO [Document]
runQuery pipe query = access pipe master "nutrition" (find query >>= rest) 

main = do
  pipe <- connect $ host "127.0.0.1"
  scotty 3000 $ do
    get "/" $ do
      res <- liftIO $ runQuery pipe (select [] "stock_foods")
      text $ T.pack $ show res

您会看到在启动Web应用程序时,如何仅创建一次数据库连接(pipe)。随后,数千甚至数百万的访客将会击中&#34; /&#34;同时路由并使用相同的连接(pipe)从数据库中读取。

我对如何正确使用Database.MongoDB

有疑问
  1. 这是正确的设置方式吗?而不是为每次访问&#34; /&#34;创建数据库连接。在后一种情况下,我们可以同时拥有数百万个连接。气馁了吗?这种方法有哪些优点和缺点?
  2. 在上面的应用程序中,如果由于某种原因数据库连接丢失并需要再次创建会发生什么?你会如何从中恢复?
  3. 使用auth function进行身份验证怎么样?是auth函数只能在创建pipe后调用一次,还是应该在每次点击时调用&#34; /&#34;?
  4. 有人说我应该使用游泳池(Data.Pool)。看起来这只会限制同时使用相同数据库连接的访问​​者数量。但为什么我要这样做呢? MongoDB连接是否内置了对同时使用的支持?

2 个答案:

答案 0 :(得分:2)

  1. 即使您为每个客户创建连接,您也无法创建太多连接。你会打ulimit。一旦你达到ulimit,遇到这个ulimit的客户端将收到运行时错误。 它没有意义的原因是因为mongodb服务器将花费太多时间轮询所有这些连接,并且它将只有你的数据库服务器拥有的那么多有意义的工作者。 一个连接并不是一个坏主意,因为mongodb旨在发送多个请求并等待响应。所以,它会利用你的mongodb只有一个限制的资源 - 你只有一个用于写入的管道,如果它意外关闭,你需要自己重新创建这个管道。 因此,拥有一个连接池更有意义。它不需要很大。我有一个应用程序,它验证用户身份并给他们提供令牌。每秒有2500个并发用户,它只有3-4个并发连接到数据库。
  2. 以下是连接池为您提供的好处:

    • 如果达到池连接限制,则将等待下一个可用连接,并且不会出现运行时错误。所以,你的应用程序会稍微等一下,而不是拒绝你的客户。

    • 游泳池将为您重新创建连接。您可以将池配置为关闭多余的连接,并根据需要创建更多直到某个限制。如果您在读取或写入时断开连接,则只需从池中获取另一个连接。如果您没有返回到池池的断开连接,则会为您创建另一个连接。

      1. 如果数据库连接已关闭,则:此连接上的mongodb侦听器将退出终端上的错误消息,您的应用程序将收到IO错误。为了处理此错误,您需要创建另一个连接并重试。在处理这种情况时,您了解使用数据库池更容易。因为最终你对此的解决方案非常类似于连接池。

      2. 作为打开连接的一部分,我做了一次身份验证。如果您以后需要再授权其他用户,您可以随时执行此操作。

      3. 是的,mongodb处理同时使用,但就像我说它只能写一个管道而且它很快变成瓶颈。如果您创建的连接数至少与mongodb服务器可以提供处理它们的线程(CPU数量)一样多,那么它们将全速运行。

    如果我错过了什么,请随时要求澄清。 谢谢你的提问。

答案 1 :(得分:1)

您真正想要的是数据库连接池。看看this other answer中的代码。

如果您的MongoDB服务器处于安全模式,则可以使用auth代替withMongoDBPool