首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Postgresql和.Net -具有多端点的连接池

Postgresql和.Net -具有多端点的连接池
EN

Stack Overflow用户
提问于 2021-05-13 03:03:29
回答 2查看 2K关注 0票数 7

Basic简介:

连接字符串:Host=IP;Port=somePort;Username=someUser;Password=somePass;Database=someDb;Maximum Pool Size=100

我的web应用程序有几十个端点可以通过WS和HTTP获得。这些端点中的每一个都打开一个新的NPGSQL连接(都使用与上面相同的连接字符串),处理数据,然后通过using语句关闭。

问题:当应用程序重新启动进行更新时,通常会有2-3,000个用户重新连接。这通常会导致有关连接池已满以及由于已经有太多客户端而拒绝新连接的错误。然而,一旦它终于可以在线,它通常只使用5-10之间的连接,在任何给定的时间。

问题:是使用连接池的正确方法下面的逻辑吗?每个端点使用相同的连接字符串创建一个新的NPGSQL连接,指定一个100的连接池?

看起来,连接池通常高达100,但在DB查看器中,这些连接的80/100显示为空闲,新的连接请求由于池溢出而被拒绝。

更好的选择?我也可以尝试通过缓慢地允许新用户重新连接来强制一个更“优雅”的启动,但是我不确定用每个端点创建一个新连接的逻辑是否正确。

代码语言:javascript
复制
// DB Connection String - Used for all NPGSQL connections
const string connectionStr "Host=IP;Port=somePort;Username=someUser;Password=somePass;Database=someDb;Maximum Pool Size=100";

// Endpoint 1 available via Websocket
public async Task someRequest(someClass someArg)
{
    /* Create a new SQL connection for this user's request using the same global connections string */
    using var conn = new NpgsqlConnection(connectionStr);
    conn.Open();

    /* Call functions and pass this SQL connection for any queries to process this user request */
    somefunction(conn, someArg);
    anotherFunction(conn, someArg);

    /* Request processing is done */
    /* conn is closed automatically by the "using" statement above */
}

// Endpoint 2 available via Websocket
public async Task someOtherRequest(someClass someArg)
{
    /* Create a new SQL connection for this user's request using the same global connections string */
    using var conn = new NpgsqlConnection(connectionStr);
    conn.Open();

    /* Call functions and pass this SQL connection for any queries to process this user request */
    somefunction(conn, someArg);
    anotherFunction(conn, someArg);

    /* Request processing is done */
    /* conn is closed automatically by the "using" statement above */
}

// endpoint3();
// endpoint4();
// endpoint5();
// endpoint6();
// etc.

编辑:通过关闭连接并在处理过程中将它们发送回池,我已经做了建议的更改。然而,这个问题在启动时仍然存在。

  1. 应用程序启动-100个连接声称池。几乎所有的人都无所事事。应用程序接收连接池耗尽错误,甚至几乎没有事务处理。

  1. Transactions突然开始翻腾,不知道为什么?这是在某种暂停之后吗?我知道文档中有某种300秒的超时默认值.这可能与这里相匹配。

  1. Transactions再次锁定,池耗尽错误恢复。

  1. Transactions尖峰和恢复,用户请求开始再次通过。

  1. 应用程序级别正常。

编辑2:这个启动问题似乎总是需要5分钟才能清除空闲事务的死锁,并开始运行所有查询。

我知道5分钟是idle_in_transaction_session_timeout的默认值。然而,这次我试着在启动时运行SET SESSION idle_in_transaction_session_timeout = '30s';10s,但它似乎丝毫没有影响到它。

我不知道为什么这100个池连接会像启动时那样处于空闲状态,需要5分钟才能清除并允许查询运行,如果是这样的话……

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-08-17 22:14:15

我忘了用一些最新的信息更新这篇文章。我在代码中做了一些其他的内部优化。

主要的问题之一就是简单地将conn.Open();改为await conn.OpenAsync();,将conn.Close();改为conn.CloseAsync();

我所拥有的其他一切都是正确的异步,但是对于NPGSQL中的所有新连接,仍然存在IO阻塞,导致大突发导致性能下降。

这是一个非常明显的变化,但我甚至没有想到要为连接的打开和关闭寻找一个异步方法。

票数 2
EN

Stack Overflow用户

发布于 2021-05-13 13:47:02

一旦在代码中关闭连接,就会释放到池中。从您编写的内容来看,在请求的整个时间内都是打开的,因此基本上1 user =1连接和池只是用作等待室(默认情况下是15秒的timeout设置)。每次需要访问DB时,打开/关闭连接,这样连接就会返回到池中,当在.net代码中花费时间时,其他用户可以使用该连接。

例如,在伪代码中:

代码语言:javascript
复制
Enter function  
 Do some computations in .net, like input validation

  Open connection (grab it from the pool)
    Fetch info#1  
  Close connection (return it to the pool)

 Do some computations in .net, like ordering the result, computing an age from a date etc 
  
  Open connection (grab it from the pool)
    Fetch info #2   
  Close connection (return it to the pool)

 Do some computations in .net

Return
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67513375

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档