Rust 从入门到放弃,再入门到贡献 nacos-sdk-rust

简介: Rust 上手难度大?我想是的。从文章标题便可知一二,小编水平有限经历了多次入门,得来的经验之谈。本文不涉及详细的技术剖析,仅表达入门的心路历程,供客官参考。## 1、初次入门初听 Rust 性能彪悍,内存安全,对比 C 来的保证不会有内存泄漏;也就是说 Rust 有 C 同等的性能而又保证了内存安全。牛!!!故而尝试开启了初次入门之旅。当时从多方搜索引擎中涉猎 Rust 相关话题和知识

Rust 上手难度大?我想是的。从文章标题便可知一二,小编水平有限经历了多次入门,得来的经验之谈。本文不涉及详细的技术剖析,仅表达入门的心路历程,供客官参考。

1、初次入门

初听 Rust 性能彪悍,内存安全,对比 C 来的保证不会有内存泄漏;也就是说 Rust 有 C 同等的性能而又保证了内存安全。牛!!!故而尝试开启了初次入门之旅。

当时从多方搜索引擎中涉猎 Rust 相关话题和知识,ATA、知乎、Bilibili、科学上网等。

也不记得是在哪个渠道,看到说 Rust + WebAssembly 是下一代云计算的未来。

于 2022-01-17 写了如下的第一行 Rust 代码
Rust_Wasm

涉猎的资料五花八门,断断续续零零碎碎,也没有持续地编码参与项目开发,对所有权、生命周期这些核心概念没有领悟,宣告了初次入门失败

2、再次入门

历经了很长一段在放弃与相关话题的持续关注之间,还是好奇心作怪,发现最佳入门辅助手册 《Rust语言圣经(Rust Course)》,仅代表小编自我观点(英文水平不足等等)。

多次翻阅『圣经』,Rust 基础入门、所有权/借用、特征对象、生命周期、异步编程、Cargo 包管理等。搭配看一些开源社区的项目:sentinel-rust/skywalking-rust/opentelemetry-rust/dubbo-rust/... 于实际项目中的运用。

skywalking-rust 知道 tonic 的使用及查看其构建 api,发觉作为 grpc 客户端并不需要 build_server 只留 build_client,故而笔者提交了第一行 Rust Chore(tonic-build): set tonic-build.build_server(false), do not build Server code.

『圣经』推荐了好几个不错的组件:

  • serde-rs/json 超高性能的通用序列化/反序列化框架,快到上天的 JSON 库,Rust 序列化 json 的事实标准。
  • tonic 完全 Rust 实现的 gRPC 客户端和服务器端。
  • tokio-rs/tokio 最火的异步网络库,除了复杂上手难度高一些外,没有其它大的问题。tokio 团队提供了多个非常优秀的 Rust 库,用户认可度很高。
  • tokio-rs/prost tokio 出品的 Protocol Buffers 工具,简单易用,文档详细。
  • tokio-rs/tracing 强大的日志框架,同时支持 OpenTelemetry 格式,无缝打通未来的监控。

感觉时机半熟,由此决定为 Nacos 开发 Rust 版的客户端,亦作为自己上手的目标去牵引持续下去。

3、nacos-sdk-rust

始于 2022-07-06,提交 README.md 说明 Nacos 客户端与服务端的交互逻辑,客户端需要实现的能力。

简要描述 client & server 的交互

请关注 proto/nacos_grpc_service.proto 并知晓构建出客户端侧的 stub,实现同步调用 service Request.request(),流式交互 service BiRequestStream.requestBiStream()。

tonic 创建与 Nacos-server 的 gRPC 双工长链接,serde/json 适配与 server 的交互序列化;

gRPC 交互的 Payload 和 Metadata 由 Protocol Buffers 序列化,具体的 Request/Response 实体 json 格式二进制数据维护于 Payload.body,类型名字符串维护于 Metadata.type 。

有了 gRPC 双工长链接,也有了数据序列化方式,那么就是对 Request/Response 的处理逻辑啦; 而 client 会接受 server 的主动调用,故可以实现一个通用的 RequestHandler 接受 server 的请求,根据 Request 类型分发到具体的处理实现并返回对应的 Response。

而 client 请求 server 的部分,则 do it ...

以上交互务必参考 java nacos-client 和 nacos-server 的实现。

3.1、异步/跨线程是极大门槛

如上的简要描述中,模型定义及序列化,朴素的编码都能写出来,而难点在于 gRPC 的交互,客户端构建后如何跨线程被使用?既能在需要的时候拿到它发起调用,又能实时捕获到服务端返回的数据然后作出处理并回应?在所有权/生命周期等约束下,异步/跨线程等应该是个极大的门槛!

遇到了难题焦头烂额,期间中断了提交,有些消沉而又继续抱着『圣经』看看并在 tracing 订阅了解中看到 tokio-rs/console,好奇它是怎么和应用交互并能实时地返回信息显示在界面上?

阅读它的源码找准了关键点,tonic 发起于应用的交互然后并发线程 loop 取得 gRPC 持续地等待服务端推送数据,然后执行逻辑。搭配看起来就很牛,谁先返回则执行其分支的 tokio::select! { xx=>, yy=>, zz=> }

  • 分支1:等候 gRPC 服务端来的数据,使用 tx: Sender 将其发往 mpsc::channel
  • 分支2:等候 rx: Receiver 接收分支1中的数据并处理;
  • 分支3:以上两个分支均不执行,则处理一些日常逻辑。

俗话说参考借鉴(抄袭)tokio-rs/console 中这部分的逻辑(拷贝过来改改)能用!数据交互不堵塞,还会断线自动重连。

3.2、gRPC 交互改用

逻辑是写好了,发觉运行不起来!总是卡在了什么地方,研究了一段时间,看 tonic 的 api 粗浅理解每次发起请求只能丢进去一个有界的 stream 流,这点在 Nacos 的交互模式里会非常难(客户端发起 stream 请求后,客户端/服务端都不会 close 结束它,而是一直持有它用作后续服务端主动推通知)决定了当前不合适。挣扎了蛮久无界流则没能发出请求,有界流难道客户端要无限重发请求?

再从『圣经』知道 tikv/grpc-rs 也是优选的 gRPC 客户端,它 wrap 了 gRPC 官方 C++ 库,看看 api 感觉可以,便尝试了确实好用。所以替换 tonic 改用 tikv/grpc-rs

3.3、加入 nacos-group

从第一行 nacos-sdk-rust 开始,两个月处于学习中的断断续续提交,然后提案由 Nacos PMC 认可故而迁入 nacos-group;随即发布了第一版 nacos-sdk=0.1.1,支持配置获取与订阅、客户端自动重连。

后来有 @onewe 同学的加入负责服务注册模块功能的开发,和我“先能用”的想法不同,他要求高,直接就从宏入手,交互模型的通用部分由宏(nacos-macro)统一生成,模型和 grpc 交互都重新定义了一番。

在框架内自定义 Event 事件抽象中 @onewe 使用了 TypeId + Any,居然有反射的韵味!大哥我大受震惊,可真是个小宝贝。

小编思维局限于 loop tokio::select!{} 一直没能优化 gRPC 交互逻辑,后来也是由 @onewe 新构建了这部分,并能自动重连、解决同一地址 gRPC 默认复用同一链接的问题。

最后历经近百次提交,完善并发布了 nacos-sdk=0.2.x 配置管理/服务注册功能均可用,包括登陆鉴权、配置解密插件。
nacos-sdk-rust-contributors

4、总结

推荐入门辅助手册 《Rust语言圣经(Rust Course)》
总的来说 Rust 入门需要花费一些时间,最好有持续的目标去牵引。参与开源社区 Rust 项目是个相对较好的方式,会有小伙伴与你一道前行。或许你还能收获一份友谊,虽友人素未谋面。

入门后方能发觉现代不少数据库都使用 Rust 语言开发,不限于分布式存算分离 HTAP 数据库 TiDB 之下 TiKV,云原生数仓 Databend,蚂蚁开源的 CeresDB,创业中的时序数据库 GreptimeDB;亦有很多其他基础设施,微内核虚拟化安全容器 Kata-Containers,隐私计算 Teaclave (Apache incubating) and so on...

大名鼎鼎的 Linus(竖中指.jpg)都已接纳 Rust on Linux,你不来试试嘛?

目录
相关文章
|
26天前
|
Rust 安全 Java
编程语言新宠:Rust语言的特性、优势与实战入门
【10月更文挑战第27天】Rust语言以其独特的特性和优势在编程领域迅速崛起。本文介绍Rust的核心特性,如所有权系统和强大的并发处理能力,以及其性能和安全性优势。通过实战示例,如“Hello, World!”和线程编程,帮助读者快速入门Rust。
48 1
|
27天前
|
Rust 安全 编译器
编程语言新宠:Rust语言的特性、优势与实战入门
【10月更文挑战第26天】Rust语言诞生于2006年,由Mozilla公司的Graydon Hoare发起。作为一门系统编程语言,Rust专注于安全和高性能。通过所有权系统和生命周期管理,Rust在编译期就能消除内存泄漏等问题,适用于操作系统、嵌入式系统等高可靠性场景。
38 2
|
28天前
|
Rust 安全 云计算
Rust语言入门:安全性与并发性的完美结合
【10月更文挑战第25天】Rust 是一种系统级编程语言,以其独特的安全性和并发性保障而著称。它提供了与 C 和 C++ 相当的性能,同时确保内存安全,避免了常见的安全问题。Rust 的所有权系统通过编译时检查保证内存安全,其零成本抽象设计使得抽象不会带来额外的性能开销。Rust 还提供了强大的并发编程工具,如线程、消息传递和原子操作,确保了数据竞争的编译时检测。这些特性使 Rust 成为编写高效、安全并发代码的理想选择。
18 0
|
6月前
|
Rust Linux iOS开发
【Rust学习】01_入门准备
让我们开始您的 Rust 之旅吧!有很多东西要学,但每一段旅程都是从第一步开始的,在本章中,我们将一起来学习以下知识点: - 在 Linux、macOS 和 Windows 上安装 Rust - 编写打印程序 Hello, world! - 使用 cargo Rust 的包管理器和构建系统
79 1
|
6月前
|
Rust 开发者
Rust函数入门与函数重载
Rust函数入门与函数重载
122 0
|
7月前
|
Web App开发 Rust 安全
一名C++程序员的Rust入门初体验
作者最近尝试写了一些Rust代码,本文主要讲述了对Rust的看法和Rust与C++的一些区别。
|
7月前
|
Rust 算法 开发者
【Rust 控制流入门指南】 Introduction to Control Flow in Rust
【Rust 控制流入门指南】 Introduction to Control Flow in Rust
57 0
|
Rust
Rust 基础入门 —— 语句与表达式
语句与表达式 这一节,我们接触的是rust中的有一个基本类型 我将其称之为 —— 逻辑结构,这个是我自己命名的,但我觉得很贴切。
60 3
|
Rust Go
Rust 基础入门 —— 字符、布尔、单元 类型
布尔类型(bool) 说明一点,bool类型的应用场景 主要就是用在流程控制中,
116 2
|
存储 Rust JavaScript
Rust 基础入门 —— 基本类型
当然,作为强类型,也不一定要全部推导,可以通过对变量进行类型标注的操作,完成对类型的显式说明,通过这样的方式就可以减小推导时间,特别是在复合类型中应用这样的方式。
51 1