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显示为空闲,新的连接请求由于池溢出而被拒绝。
更好的选择?我也可以尝试通过缓慢地允许新用户重新连接来强制一个更“优雅”的启动,但是我不确定用每个端点创建一个新连接的逻辑是否正确。
// 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.编辑:通过关闭连接并在处理过程中将它们发送回池,我已经做了建议的更改。然而,这个问题在启动时仍然存在。

编辑2:这个启动问题似乎总是需要5分钟才能清除空闲事务的死锁,并开始运行所有查询。
我知道5分钟是idle_in_transaction_session_timeout的默认值。然而,这次我试着在启动时运行SET SESSION idle_in_transaction_session_timeout = '30s';和10s,但它似乎丝毫没有影响到它。
我不知道为什么这100个池连接会像启动时那样处于空闲状态,需要5分钟才能清除并允许查询运行,如果是这样的话……
发布于 2021-08-17 22:14:15
我忘了用一些最新的信息更新这篇文章。我在代码中做了一些其他的内部优化。
主要的问题之一就是简单地将conn.Open();改为await conn.OpenAsync();,将conn.Close();改为conn.CloseAsync();。
我所拥有的其他一切都是正确的异步,但是对于NPGSQL中的所有新连接,仍然存在IO阻塞,导致大突发导致性能下降。
这是一个非常明显的变化,但我甚至没有想到要为连接的打开和关闭寻找一个异步方法。
发布于 2021-05-13 13:47:02
一旦在代码中关闭连接,就会释放到池中。从您编写的内容来看,在请求的整个时间内都是打开的,因此基本上1 user =1连接和池只是用作等待室(默认情况下是15秒的timeout设置)。每次需要访问DB时,打开/关闭连接,这样连接就会返回到池中,当在.net代码中花费时间时,其他用户可以使用该连接。
例如,在伪代码中:
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
Returnhttps://stackoverflow.com/questions/67513375
复制相似问题