Rust真的适合写业务后端吗?

Rust一直以难度大、学习成本高著称,最明显的可能就是所有权以及生命周期的问题。

然而,如果大家真正使用过一段时间的Rust后,会发Rust其实非常好用,尤其是对于业务代码,Rust的无Null设计以及Result模式,能够在开发阶段避免不少问题,并且使得代码更清晰可读。而在大部分场景下,都不会涉及到生命周期问题,编译器能够隐式的推断出生命周期。而所有权系统使得我们不得不思考代码是否合理,如果因为所有权问题导致编译不过,那可能是设计问题,想一想是否需要重构当前代码。

今天以一个知识库的后端开发为例,来看一下Rust到底是否适合后端业务开发。

背景

今年上半年使用Rust写了一个知识库,主要功能是导入一些文档,经过编码后保存到本地向量库,并接入AI模型和MCP,实现智能问答的效果,也就是所谓的RAG。

目前暂未开源,详情可了解:https://fskb.coderbox.cn

这个项目除UI部分外,完全使用Rust开发,以下是Rust的代码行数统计(不含依赖库)。

Language Files Lines Code Comments Blanks
Rust 194 20695 17672 1044 1979
- Markdown 119 1701 39 1582
(Total) 22396 17711 2626 2059
Total 194 20695 17672 1044 1979

从开始开发到初版完成,耗时1个月左右,而在此过程中,实际上遇到的比较麻烦的问题不是Rust语言本身的问题,而是如何在本地提取各种文档里的内容的问题。

为什么选择Rust

作为一个需要支持多种系统部署的本地化应用,跨平台是必须的,而知识库获取内容的主要来源是通过解析文件并提起其中的内容,而这部分内容很可能需要调用第三方库实现,并且要保证解析性能。综合下来,Rust是适合的。

另外,我们希望这是一个本地化应用,需要能够快速部署在用户的电脑或者服务器上,并能够稳定运行,这也与Rust的特性相符,能够做到跨平台编译,并且编译后的可执行文件的体积较小(除过资源文件,大约40M左右)。

框架选型

虽然Rust生态确实不如Java生态丰富,但是基本上常见的功能在Rust中都有对应的实现。

以下大致列出了Java中的常用库在Rust中对应的替代选项。

Java库 Rust替代品
Spring Web Actix Web, Rocket, Axum
MyBatis(Plus) Diesel, Sea ORM, RBatis
Apache Commons itertools, regex, chrono
Log4j log, env_logger, tracing
Jackson、Fastjson serde, serde_json
HttpClient reqwest
Redis redis-rs
Kafka、RabbitMQ rdkafka, lapin、JetStream
Reactor tokio

Rust中暂时还没有类似Spring Boot这样的集成框架,也没有像Spring Cloud这样的微服务框架。但这并不是说Rust开发的应用不能使用微服务模式,因为微服务本身核心是服务发现,而不少老牌的服务注册中心也都提供了Rust版的客户端,用于服务的注册和发现,使用起来也和其他语言类似。

我们也开源了一个服务配置和注册中心的应用,参考了Nacos的设计,开源地址为:https://github.com/xgpxg/conreg

在知识库项目中,我们最终选用的主要框架有以下几个:

• 基础Web框架: Rocket

• ORM框架:RBatis

• 缓存:Redis和Sled+Moka。Redis在集群模式下使用,Sled+Moka在单机模式下使用

• 数据库:Sqlite和MySQL

• 序列化/反序列化:serde、serde_json

这些都是在业务开发中非常常用的库,使用起来都非常容易上手。

其中,增删改查主要会用到RBatis,这是一个和MyBatis类似的库,提供了基本的ORM功能。它也支持动态SQL和分页查询,支持自定义SQL。

Rust写业务代码效率如何

后端开发,一般以业务为主,会涉及不少复杂的数据结构以及调用关系,如果没有亲自使用Rust写过业务代码的同学,可能都会觉得Rust的限制太多,一写一个错。但实际上并不会存在这些问题,相反,大部分时候是写的很顺畅的,包括生命周期和所有权机制,使用多了后,你会发现它就是合理的,这些规则就是能避免大部分内存问题,并且你也会思考,一个变量应该什么时候不需要再使用,避免过长时间占用内存,不知不觉的就会写出高性能代码。而在以往的Java项目中,一个对象,可能会经过十几个甚至几十个方法,很难知道哪个方法会修改这个对象,而Rust的可变性与不可变性规则就能简化这类问题,通过参数定义是否为mut的,就知道是否会修改里边的值(内部可变性除外)。

Java中的Spring Web提供了Web开发的基本框架,通过一个注解就能开启一个HTTP端点,例如:

java 复制代码
@RestController
public class TestController {
    @GetMapping("/hello")
    public String hello() {
        return "World";
    }
}

而Rust中的Web框架则使用宏实现类似注解的功能。

以Rocket为例:

rust 复制代码
#[get("/hello")]
pub fn hello() -> String {
    "World".to_string()
}

它们非常相似,并且Rust的代码看起来更简洁一点点。

其实在很多场景下,Rust的代码和Java有相似之处,这也是因为Rust是融合了其他语言的一些优势,逐渐发展起来的,虽然它本身不算是一个面向对象的编程语言,但是具有面向对象的部分特性。

至于令人头疼的生命周期,在项目的1.7万行代码中,也仅需要手动标记了38处,其它都无需显示标注。

使用Rust写业务代码时,只要稍微细心一点,能够编译通过,运行起来,基本上不会有太大问题,减少了不少调试时间。

在这个知识库项目之后,我们又做了一些其他的Rust实现的项目,例如:使用Tauri实现的个人知识库客户端、服务配置和注册中心、AI网关以及其他的一些小工具,累计代码量也达到了10万行。就开发效率而言,其实是和Java是差不多的。而编译后程序本身大小以及占用内存比Java程序小很多,实测知识库应用在未加载本地模型情况下,占用内存稳定在70M左右。

Rust用于实现高性能的后端服务

我们以一个空接口为例,分别测试了Java(17)和Rust的QPS。Web框架分别为Spring Web和Rocket,均使用默认配置,未做任何优化,测试环境相同。

Java测试代码:

java 复制代码
@RestController
class TestController {
    @GetMapping("/hello")
    public String hello() {
        return "World";
    }
}

Rust测试代码

rust 复制代码
#[get("/hello")]
fn hello() -> &'static str {
    "World"
}

Java测试结果:

Rust测试结果:

Rust版的比Java版的快了3倍左右。

以上这个简单的测试虽然不能直接定义Rust比Java快,但是在我们网关项目中,在经过一些列处理(鉴权、安全验证、过滤器、接口调用等)后,未做优化的情况下,仍然能达到2w+的QPS,可见使用Rust作为后端服务,能够提升不少的性能。

这些性能的提升一方面得益于语言本身,因为Rust编译器在编译时做了一系列优化,使得能够以接近C语言的效率执行,另一方面也是因为框架的原因,Rocket当前默认使用Tokio异步执行,能够提升并发度,而Java中也可以使用WebFlux来异步运行,从而提升性能。

使用Rust重构以节约成本

之前提到了,Rust有很好的性能,而这些性能提升带来的直接价值就是能够节省机器资源,如果使用Rust实现后,能够提升3倍性能,那就可以减少2/3的服务器成本,当服务数量众多时,这也是一笔不小的费用。

当然,对现有系统使用Rust重构本身也是一个不小的成本,对于存量系统,可以对性能要求较高的部分使用Rust重写,对于新系统则可以完全使用Rust实现。

总结

Rust虽然作为一门系统级的语言,但是在后端业务开发中,它也是非常适合的,只是看起来比较难而已,当开发新系统时,可以考虑使用Rust,能够带来不小的收益。

Rust的生态也正在逐步完善,并且大家常说的编译慢的问题目前版本也有所改善,未来也会有更多的应用使用Rust重写。

相关推荐
要加油GW7 小时前
python使用vscode 需要配置全局的环境变量。
开发语言·vscode·python
不爱学英文的码字机器7 小时前
深度解析《AI+Java编程入门》:一本为零基础重构的Java学习路径
java·人工智能·后端·重构
B站计算机毕业设计之家7 小时前
python图像识别系统 AI多功能图像识别检测系统(11种识别功能)银行卡、植物、动物、通用票据、营业执照、身份证、车牌号、驾驶证、行驶证、车型、Logo✅
大数据·开发语言·人工智能·python·图像识别·1024程序员节·识别
IT_陈寒7 小时前
Vue3性能翻倍秘籍:5个Composition API技巧让你的应用快如闪电⚡
前端·人工智能·后端
ceclar1237 小时前
C++日期与时间
开发语言·c++
懒羊羊不懒@8 小时前
JavaSe—泛型
java·开发语言·人工智能·windows·设计模式·1024程序员节
Zhangzy@8 小时前
Rust Workspace 构建多项目体系
开发语言·前端·rust
Zhang青山8 小时前
使用 Nginx 轻松处理跨域请求(CORS)
java·后端
麦麦鸡腿堡8 小时前
Java的三代日期类(Date,Calendar,LocalDateTime)
java·开发语言