【发布时间】:2020-07-12 21:00:39
【问题描述】:
我有一个连接到 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
}
【问题讨论】:
-
从文档中不清楚
prepare()是否创建了服务器端prepared statement。如果是这样,那么这些将堆积在服务器上的共享连接中,因为您使用的是字符串格式而不是绑定参数。如果您可以放入调试查询,请查看select * from pg_prepared_statements的返回结果 -
运行我所有的 HTTP 请求并且 RAM 仍然被分配,即使所有请求都是服务,我做了那个选择并得到 0 行返回
-
您是否使用相同的数据库连接/会话进行操作?准备好的语句仅在声明它们的会话中可见。如果你这样做了,那么对不起猜测错误。
-
@MikeOrganek,看来你是对的!在每个唯一的
a和b值查询之后,我看到pg_prepared_statements的计数在增加。你会建议我如何解决这个问题?
标签: postgresql rust rust-actix actix-web