本章将在上一章的基础上,将 consul_api
集成到我们的 gPRC 和 web 服务中,实现服务的自动注册和自动发现。
本章将以 echo-srv
和 echo-web
进行讨论,calc-srv
和calc-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(®).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(®).await.unwrap();
println!("服务注册成功");
}
服务的自动发现
除了将自己作为服务进行注册,echo-web
还需要自动发现 echo-srv
(calc-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-srv
和calc-web
的服务自动注册和发现 - 请优化
echo-web
中的服务发现:- 服务发现是否可以在
main()
中实现:- 通过 axum 共享
echo-web
服务的信息
- 通过 axum 共享
- 有能力的话,可以为服务发现开发一个连接池
- 服务发现是否可以在