本章将在上一章的基础上,将 consul_api 集成到我们的 gPRC 和 web 服务中,实现服务的自动注册和自动发现。

本章将以 echo-srvecho-web 进行讨论,calc-srvcalc-web请自(fu)行(zhi)实(dai)现(ma)。

echo-srv 的自动服务注册

编写服务注册函数

async fn register(addr: &str) {
    println!("正在注册服务");
    let addrs: Vec<&str> = addr.split(":").collect();
    let addr = addrs[0];
    let port: i32 = addrs[1].parse().unwrap();
    let opt = consul_api::ConsulOption::default();
    let cs = consul_api::Consul::new(opt).unwrap();
    let reg = consul_api::Registration::simple("echo-srv", addr, port);
    cs.register(&reg).await.unwrap();
    println!("服务注册成功");
}

服务的自动注册

echo-web 的自动服务注册与发现

服务的自动注册

#[tokio::main]
async fn main() {
    let addr = "0.0.0.0:29527";
    tokio::spawn(register(addr));

    let app = axum::Router::new().route("/echo", 
     //...
}

async fn register(addr: &str) {
    println!("正在注册服务");
    let addrs: Vec<&str> = addr.split(":").collect();
    let addr = addrs[0];
    let port: i32 = addrs[1].parse().unwrap();
    let opt = consul_api::ConsulOption::default();
    let cs = consul_api::Consul::new(opt).unwrap();
    let reg = consul_api::Registration::simple("echo-web", addr, port);
    cs.register(&reg).await.unwrap();
    println!("服务注册成功");
}

服务的自动发现

除了将自己作为服务进行注册,echo-web还需要自动发现 echo-srvcalc-web也一样要自动发现 calc-srv)。

async fn discovery(service_id: &str) -> Result<String, String> {
    println!("正在发现服务 {}", service_id);
    let opt = consul_api::ConsulOption::default();
    let cs = consul_api::Consul::new(opt).unwrap();
    let filter = consul_api::Filter::ID(service_id.into());
    let srv = cs
        .get_service(&filter)
        .await
        .map_err(|err| err.to_string())?;
    if let Some(srv) = srv {
        return Ok(format!("http://{}:{}", srv.address, srv.port));
    }
    Err("没有发现指定的服务".to_string())
}
//...
async fn echo(Form(EchoInput { message }): Form<EchoInput>) -> Result<Html<String>, String> {
    let echo_srv_addr = discovery("echo-srv").await?;
    let mut client = pb::echo_serivce_client::EchoSerivceClient::connect(echo_srv_addr)
        .await
        .map_err(|err| err.to_string())?;
  //...
}

作业

  • 请实现 calc-srvcalc-web的服务自动注册和发现
  • 请优化 echo-web 中的服务发现:
    • 服务发现是否可以在 main() 中实现:
      • 通过 axum 共享 echo-web 服务的信息
    • 有能力的话,可以为服务发现开发一个连接池