spring boot迁移计划 第Ⅰ章 --chapter 1. rust hyper 结合rust nacos-client开发nacos网关 part ④ nacos-client
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;
//由于nacos不广播权重配置的更改,而且nacos内置了raft和负载均衡算法所以改为每次去注册中心请求一个服务地址
//LazyLock延迟加载,ArcSwap+AhashMap提高性能
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();
//这里小小的吐槽一下rnacos的大神,希望能把这个u32的端口号类型更新成跟其他工具一样,我看作者说用的actix-web,我试过actix,它的端口号也是u16的哈
connect(
&server_name,
server_port,
&nacos_ip,
nacos_port,
&nacos_group_name,
);
//add_naming_listener(&server_name).await;
}
//注册
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) //使用grpc,不用可以设置为false
.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();
//向nacos注册
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);
//add_naming_listener(service_name).await;
target_address
}
Err(e) => {
error!("select_instance error {}", &e.to_string());
"".to_owned()
}
}
}
spring boot迁移计划 第Ⅰ章 --chapter 1. rust hyper 结合rust nacos-client开发nacos网关 part ④ nacos-client的更多相关文章
- spring boot 笔记--第三章
spring boot 笔记 第三章,使用Spring boot 构建系统: 强烈建议支持依赖管理的构建系统,Maven或Gradle 依赖管理: Spring Boot的每版本都会提供它支持的依赖列 ...
- 携程Apollo(阿波罗)配置中心Spring Boot迁移日志组件,使用配置中心进行管理的思路
说明: 1.Spring Boot项目默认使用logback进行日志管理 2.logback在启动时默认会自动检查是否有logback.xml文件,如果有时会有限加载这个文件. 3.那么如果是用配置中 ...
- 《spring boot》8.2章学习时无法正常启动,报“ORA-00942: 表或视图不存在 ”
在学习<spring boot>一书的过程中,由于原书作者难免有一些遗漏的的地方,或者系统.软件版本不一致.框架更新等各种因素,完全安装书中源码页不能实现项目的正常启动 在8.2章节,演示 ...
- Spring Boot 2.0 迁移指南

目录 目 录第一部分 点睛Spring 4.x第1 章 Spring 基础 .............................................................. ...
- 【原】spring boot在整合项目依赖的问题
最近要开发新的项目,就花了几天时间看了下spring boot的相关资料,然后做了一个demo,不得不说开发效率确实很快,几行注解就完成了事务,aop,数据库等相关配置:但由于先前习惯了spring ...
- 为什么是Spring Boot
原文:https://dzone.com/articles/why-springboot 作者:Siva Prasad Reddy Katamreddy 译者:Oopsguy 本文介绍将各种Sprin ...
- Spring Boot快速入门(最新)
本章通过完成Spring Boot基础项目的构建并实现一个简单的Http请求处理,让大家对Spring Boot有一个初步的了解,并体验其结构简单.开发快速的特性.预计阅读及演练过程将花费约5分钟. ...
- Spring Boot 2.0系列文章(五):Spring Boot 2.0 项目源码结构预览
关注我 转载请务必注明原创地址为:http://www.54tianzhisheng.cn/2018/04/15/springboot2_code/ 项目结构 结构分析: Spring-boot-pr ...
随机推荐
- 如何配置 maven 编译插件的 JDK 版本
普通maven项目配置编译器版本 参考maven官方文档 Setting the -source and -target of the Java Compiler maven有2种方法设置编译JDK版 ...
- npcap实战抓包教程
npcap 是一个用于 Windows 系统的网络抓包库,基于 WinPcap 的改进版本,支持最新的 Windows 特性和协议(如 IPv6).它通常与 Wireshark 或 Nmap 等工具一 ...
- C# DataTable 类使用
命名空间: System.Data 程序集: System.Data.Common.dll 参考连接:https://docs.microsoft.com/zh-cn/dotnet/api/syste ...
- 安川MOTOMAN机器人NX100维修的注意事项
安川MOTOMAN机器人NX100维修,操作人员安全注意事项 整个机器人的最大动作范围内均具有潜在的危险性. 为机器人工作的所有人员 (安全管理员.安装人员.操作人员和机器人维修人员) 必须时刻树 ...
- sprintf用法详解
sprintf 将字串格式化. 在头文件 #include< stdio.h >中 语法: int sprintf(string format, mixed [args]...); 返回值 ...
- Hadoop - hadoop自带MR案例:词频 WordCount
词频 Word Count 1.在浏览器上访问 https://node01:9870 2.创建目录 /user 目录 bin/hdfs dfs -mkdir /user 如果未配置环境变量,需要到h ...
- 读论文-基于Python的协同过滤算法的研究与应用实现
前言 今天读的论文为一篇名为<基于Python的协同过滤算法的研究与应用实现>的论文,文章是在2019年9月发表于<电脑知识与技术>的一篇期刊论文. 摘要 随着科学技术的快速发 ...
- 分享4款.NET开源、免费、实用的商城系统
前言 今天大姚给大家分享4款.NET开源.免费.实用的商城系统,希望可以帮助到有商城系统开发需求的同学. nopCommerce nopCommerce是一个.NET开源功能丰富.免费.灵活且可定制的 ...
- thinkphp或laravel连接sql server 2014数据库
问题描述:平时使用最多为mysql数据库,目前有项目数据库为sql server 2014,列出连接全过程 首先下载安装SQLserver的odbc开放数据库链连接,下载地址:https://lear ...
- 使用Express对mysql进行增改查操作(完全代码版本)
使用Express对mysql进行增改查操作(完全代码版本) 今天发的是Express对mysql进行增删改操作的所有代码,这个代码还没有完善好,都是一些基础的增删改查操作,有一些地方也写上了注释方便 ...