postgresql - Actix Rust deadpool_postgres:未释放数据库连接
问题描述
我有一个连接到 Postgres 数据库的 Actix-web 服务器。
我注意到在 1000 次请求后,我的 Postgres DB 的 RAM 使用率飙升。
当我停止 actix-web 时,db 持有的 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 确定代码堆积了服务器端准备好的语句。
目前尚不清楚这些语句是否可以使用此库关闭。
可以使用两种方法中的任何一种来避免此问题:
- 使用单个共享的预处理语句
- 使用直接查询表单而不是准备好的语句
我原则上推荐第一种方法,因为它更有效并且可以防止 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)
}
使用此代码,应在池的每个连接上只创建一个准备好的语句。
推荐阅读
- r - ggplot2 统计密度仅适用于 y 值
- angular - Angular - 唯一标识递归 ng-content 中的元素
- xml-validation - 如何使用 DTD 在 XML 中验证 xml:lang ATTLIST?
- python - 如何在mac上用python读取CDF文件?
- php - 如何使用 PuTTY 从远程 SSH 服务器上的 PHP 中执行的命令获取结果?
- perl - 在文本文件的第二列中求和值
- php - Laravel 查询生成器左连接中的两个表
- excel - 如何使用 Excel 公式查找客户多次付款的总和?
- jquery - 如何实现这种带有背景图像和活动项目向下箭头的引导固定顶部导航栏菜单
- python - openpyxl:我无法使用密码打开 excel 文件