1. toml依赖
| nacos_rust_client = "0.3" |
| local_ipaddress = "0.1" |
| ahash = "0.8" |
| arc-swap = "1" |
2. 代码
2025-01-17更新: 新增全局服务地址缓存
| use std::sync::{Arc, LazyLock}; |
| |
| use ahash::AHashMap; |
| use arc_swap::ArcSwap; |
| use log::{error, info}; |
| use nacos_rust_client::client::{ |
| naming_client::{ |
| Instance, InstanceDefaultListener, QueryInstanceListParams, ServiceInstanceKey, |
| }, ClientBuilder |
| }; |
| |
| use crate::init::config::Config; |
| |
| |
| |
| pub static NAMING_MAP: LazyLock<ArcSwap<AHashMap<String, Arc<Vec<Arc<Instance>>>>>> = |
| LazyLock::new(|| ArcSwap::from_pointee(AHashMap::new())); |
| |
| pub async fn init_nacos() { |
| let server_name = Config::global().server_name(); |
| let server_port = Config::global().server_port(); |
| let nacos_ip = Config::global().nacos_ip(); |
| let nacos_port = Config::global().nacos_port(); |
| let nacos_group_name = Config::global().nacos_group(); |
| |
| connect( |
| &server_name, |
| server_port, |
| &nacos_ip, |
| nacos_port, |
| &nacos_group_name, |
| ); |
| |
| } |
| |
| |
| pub fn connect( |
| service_name: &str, |
| service_port: u16, |
| nacos_ip: &str, |
| nacos_port: u16, |
| nacos_group_name: &str, |
| ) { |
| let nacos_addr = &format!("{}:{}", nacos_ip, nacos_port as u32); |
| ClientBuilder::new() |
| .set_endpoint_addrs(nacos_addr) |
| .set_use_grpc(true) |
| .build_naming_client(); |
| let ip = local_ipaddress::get().unwrap(); |
| let instance = Instance::new_simple(&ip, service_port as u32, service_name, nacos_group_name); |
| let naming_client = nacos_rust_client::get_last_naming_client().unwrap(); |
| |
| naming_client.register(instance); |
| } |
| |
| |
| pub async fn add_naming_listener(service_name: &str) { |
| let naming_client = nacos_rust_client::get_last_naming_client().unwrap(); |
| let servcie_key = ServiceInstanceKey::new(service_name, &Config::global().nacos_group()); |
| let default_listener = |
| InstanceDefaultListener::new(*Box::new(servcie_key), Some(Arc::new(handle_listen_list))); |
| naming_client |
| .subscribe(Box::new(default_listener)) |
| .await |
| .unwrap(); |
| } |
| |
| |
| fn handle_listen_list( |
| instance_list: Arc<Vec<Arc<Instance>>>, |
| add_list: Vec<Arc<Instance>>, |
| remove_list: Vec<Arc<Instance>>, |
| ) { |
| let service_name = if instance_list.len() > 0 { |
| &instance_list[0].service_name |
| } else if add_list.len() > 0 { |
| &add_list[0].service_name |
| } else { |
| &remove_list[0].service_name |
| }; |
| let service_name: String = service_name.split("@@").collect::<Vec<&str>>()[1].to_owned(); |
| info!( |
| "{} instances changed, add count:{}, remove count:{}", |
| service_name, |
| add_list.len(), |
| remove_list.len() |
| ); |
| update_naming_map(&service_name, instance_list); |
| } |
| |
| pub fn update_naming_map(service_name: &str, instance_list: Arc<Vec<Arc<Instance>>>) { |
| info!("update gloable server cache : {:?}", service_name); |
| let mut map = NAMING_MAP.load().as_ref().clone(); |
| map.insert(service_name.to_owned(), instance_list); |
| NAMING_MAP.store(map.into()); |
| } |
| |
| |
| pub async fn select_service(service_name: &str) -> String { |
| let query = QueryInstanceListParams::new_simple(service_name, &Config::global().nacos_group()); |
| let naming_client = nacos_rust_client::get_last_naming_client().unwrap(); |
| match naming_client.select_instance(query).await { |
| Ok(instances) => { |
| let target_address = format!("{}:{}", &instances.ip, &instances.port); |
| |
| target_address |
| } |
| Err(e) => { |
| error!("select_instance error {}", &e.to_string()); |
| "".to_owned() |
| } |
| } |
| } |
| |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 易语言 —— 开山篇