Actix-Web + Tonic gRPC 正确集成

问题描述 投票:0回答:1

我在 actix-web 中有一个 Web 服务器,最近我构建了一个不同的 C++ 服务器。我决定实现gRPC作为两者之间的通信桥梁。但我不知道如何集成actix web + tonic(在http端点中调用gRPC调用)。我当前的解决方案是:

RPCRepository
保存所有rpc服务,并将其作为互斥体传递给
app_data
(因为rpc函数由于某种未知原因是可变的)。 但这种方法似乎违反直觉,如果我同时有 1k 个连接,为什么他们必须等待互斥锁被解锁? 我想知道我的集成是否不合适或者这就是 actix-web+tonic grpc 的限制。

// grpc.rs
pub struct RPCClientRepository {
    pub health_client: HealthCheckPingClient<Channel>,
    pub suggest_client: SuggesterClient<Channel>,
}
... rest ...

// main.rs

let grpc_ctx = Data::new(Mutex::new(grpc_repo));


println!("[INFO] HTTP Server running at port {}", PORT);
HttpServer::new(move || {
      App::new()
         .app_data(ctx.clone())
         .app_data(grpc_ctx.clone())
         .service(activities)
})
  .bind("0.0.0.0:".to_owned() + PORT)?
  .run()
  .await


// activities.rs

#[get("/activities")]
pub async fn activities(
    req: HttpRequest,
    ctx: Data<Driver>,
    rpc_repo: Data<Mutex<RPCClientRepository>>,
) -> impl Responder {

    let mut unlock = rpc_repo
        .lock()
        .unwrap();
    let suggestion = unlock
        .suggest_client
        .suggest_friends(tonic::Request::new(SuggestRequest {
            skip: 0,
            user_id: "".to_string(),
        }))
        .await;

... rest ...
rust architecture grpc actix-web rust-tonic
1个回答
0
投票

经过一番挖掘,收集了更多信息(希望是真的,如果我错了,请纠正我),我想我已经找到了答案。

在每个请求中克隆您所需的服务。

我被告知 tonic 提供了一个非常有效的克隆,所以这就是方法,而不是等待 1 个互斥体。

代码

// main.rs

let grpc_ctx = Data::new(Mutex::new(grpc_repo));


println!("[INFO] HTTP Server running at port {}", PORT);
HttpServer::new(move || {
      App::new()
         .app_data(ctx.clone())
         .app_data(grpc_ctx.clone())
         .service(activities)
})
  .bind("0.0.0.0:".to_owned() + PORT)?
  .run()
  .await


// activities.rs

#[get("/activities")]
pub async fn activities(
    req: HttpRequest,
    ctx: Data<Driver>,
    rpc_repo: Data<Mutex<RPCClientRepository>>,
) -> impl Responder {

    let mut cl = rpc_repo.suggest_client.clone();
    let res = cl.suggest_friends(tonic::Request::new(SuggestRequest {
        skip: 0,
        user_id: "id_123",
    }))
    .await;
    let data = match res {
        Ok(response) => response,
        Err(e) => {
            println!("[E] error at gRPC Activities: {}", e);
            return HttpResponse::BadGateway().finish();
        }
    };
    println!("c++ classifier returned: {} results",data.into_inner().count);

... rest ...


© www.soinside.com 2019 - 2024. All rights reserved.