Actix Rust deadpool_postgres:未释放数据库连接



我有一个连接到Postgres数据库的Actix web服务器。

我注意到在1000次请求后,我的Postgres DB的RAM使用量激增

当我停止activx web时,数据库中的RAM将被清除。这让我相信我的代码并没有释放连接

我找不到一个连接实际被释放的例子。它看起来像是在其他人的代码中推断出来的。

这是我的:

async fn hellow_world(a : f32, b : f32, pool: &Pool) -> Result<Value, PoolError> {
let client: Client = pool.get().await?;
let sql = format!("select "json" from public.table_a WHERE a={} and b={}", a, b);
let stmt = client.prepare(&sql).await?;
let row = client.query_one(&stmt, &[]).await?;
let result : Value = row.get(0);
Ok(result)
}
#[derive(Deserialize)]
pub struct MyRequest {
a: f32,
b: f32
}
#[get("/hello")]
async fn sv_hellow_world(info: web::Query<MyRequest>, db_pool: web::Data<Pool>) -> Result<HttpResponse, Error> {
let response : Value = hellow_world(info.a, info.b, &db_pool).await?;
Ok(HttpResponse::Ok().json(response))
}
#[actix_rt::main]
async fn main() -> std::io::Result<()> {
dotenv().ok();
let config = Config::from_env().unwrap();
let pool = config.pg.create_pool(tokio_postgres::NoTls).unwrap();
env_logger::from_env(Env::default().default_filter_or("info")).init();
let server = HttpServer::new(move || App::new().wrap(Logger::default()).wrap(Logger::new("%a %{User-Agent}i")).data(pool.clone()).service(sv_hellow_world))
.bind("0.0.0.0:3000")?
.run();
server.await
}

根据进一步的测试,@Werner确定代码堆积了服务器端准备好的语句。

目前尚不清楚是否可以使用此库关闭这些语句。

两种方法中的任何一种都可以用来避免这个问题:

  1. 使用一个共享的准备语句
  2. 使用直接查询表单而不是准备好的语句

原则上,我推荐第一种方法,因为它更高效,可以防止SQL注入。它应该看起来像这样:

async fn hellow_world(a : f32, b : f32, pool: &Pool) -> Result<Value, PoolError> {
let client: Client = pool.get().await?;
let stmt = client.prepare("select "json" from public.table_a WHERE a=$1::numeric and b=$2::numeric").await?;
let row = client.query_one(&stmt, &[&a, &b]).await?;
let result : Value = row.get(0);
Ok(result)
}

使用此代码,应该在池的每个连接上只创建一个准备好的语句。

最新更新