【Rust基础】Rust后端开发常用库

server/2025/3/15 10:03:02/

使用Rust有一段时间了,期间尝试过使用Rust做后端开发、命令行工具开发,以及做端侧模型部署,也尝试过交叉编译、FFI调用等,也算是基本入门了。在用Rust做后端接口开发时,常常会找不到一些合适库,而这些库在Java中却很常见,于是在此汇总一下后Rust后端开发中常用的一些库。

  • 基础框架

    首先是基础web开发框架,在Java中,最常用的就是Spring了,而Spring其实不单单是一个开发框架,而是一整个完整的生态。其中的SpringBoot更是做了很好的封装,屏蔽了非常多的细节,这也导致了从Java系的web开发转到Rust时会遇到很多问题。而在Rust中,显然没有向Spring一样完整的生态支持,所以需要我们自己把各个模块组装在一起。

    可选项:axum、actix-web、warp、rocket

    从使用方式和使用难度上来说大同小异,axum和rocket可能会更容易上手一点,个人目前使用rocket稍微多一点,它也支持通过类似于Spring注解的方式来定义接口,支持参数映射。但是,它似乎没有和SpringBoot类似的参数校验工具,比如校验最大最小值、参数长度等,目前只能自己实现相关trait来校验了,还没有发现一个很好用的校验库来实现自定义返回错误码的功能。

  • 数据库
    基本上主流的数据库Rust都是支持的,都有Rust客户端,而我们开发时更多关注的是ORM框架,在Java中最常用的非MyBatis莫属了,其实Rust中有一个类似于MyBatis的库,叫做rbatis,目前还没有尝试过,看起来还不错,也支持动态SQL,只是从xml格式变为html感觉怪怪的。另一个比较常用的就是diesel,性能确实不错,支持流式处理,也支持联表,类型安全,但是,不怎么支持动态SQL,所以针对一些复杂查询可能会写的比较费力。

    可选项:diesel、rbatis、sqlx

    其实sqlx不能算作ORM框架,但是它比较简单且灵活,适合一些小项目使用吧。

  • 缓存
    缓存算是中间件了,基本上就是看其是否有支持Rust的驱动或者SDK了。常用的Redis,有Rust版本的驱动,也叫redis。另一个是moka,一个内存缓存库,也很好用。

    可选项:redis、moka

    除了以上两个常用的外,其他缓存大部分也都有Rust版的驱动,可以在crates.io上找到

  • 池化
    数据库连接、Redis连接以及其他涉及到网络连接的,基本都会用到连接池,Java里有Hikari、C3P0、DBCP等,这些池化工具常常被用来做连接复用,连接复用的好处一是能减少频繁创建连接带来的消耗,二是可以限制连接数量,在有限的系统资源下维持系统的稳定。而在Rust中,最常用的一个池化工具就是r2d2,它本身支持了许多连接的池化,如redis、diesel、sqlx以及postgres和oracle等。我们也可以实现它的trait来管理自定义的需要池化的对象,还是很方便的

    可选项:r2d2、deadpool

    除了r2d2外,还有一个就是deadpool,它是支持异步的,而r2d2目前看是同步的,所以在并发性能上会有所提升。

  • 多线程和异步

    Rust支持async/await关键字来实现异步,但这只是一个语法,它需要一个异步的runtime来支持异步操作,最常用的莫过于tokio了,这个名字初次看到感觉也是有点怪怪的。大部分的需要异步的库都集成了tokio。要实现异步,只需要为函数加上asnyc即可,需要注意的是,要对async函数使用.await才会触发执行,否则是不会执行的,而.await又需要在async中才可以使用,所以层层嵌套到最外层到main函数,它就需要是async的了,我们可以使用#[tokio::main]来开启异步runtime。具体的tokio异步相关的一些问题,后面会再总结一下。

    可选项:tokio

    对于tokio中的spwan,它和Java线程池中的submit提交一个任务类似,spwan提交一个任务后,由tokio去调度执行,spwan会返回一个JoinHandle,有多个任务时,使用join!(task1,task2,…)来并发执行即可。使用上还是蛮简单的。

    说到多线程,那免不了线程间的通信,有一个库叫crossbeam,提供了一些原子包装类型,以及线程安全的channel,可以很方便的在多线程中交互,比标准库中的channel好用一些。

  • 错误处理

    在Java中,错误处理一般是自定义的Exception,结合业务状态码,封装一个统一的响应格式。在Rust中,没有异常的概念,虽然有panic,但是,正常来讲,在后端服务中,应该确保不会发生panic,也就是必须要手动处理错误。Rust的每一个库都会有一个它自己的自定义的异常,这些异常(即Error)会暴露给调用方来处理,我们可以通过match来匹配指定的Error,或者if let来处理对应的Error,如果函数使用Result作为返回值,还可将Error返回给外层,或者用问号?来返回给外层。但是我们通常会使用多个库,一个函数里会有多个不同类型的错误,这就需要自定义个错误枚举,来实现std下的Error,给不同的Error类型包装成统一的自定义Error,或者结合Box+dyn实现动态包裹Error。而这些操作,也可以通过第三方的库来实现,常用的就是anyhow。

    可选项:anyhow、eyre

    anyhow其实依赖于thiserror,而thiserror提供了一些宏来包裹不同类型的错误,用法也很简单。我们可以将std::result::Result替换为anyhow的Result,返回anyhow!()或者bail!(“”),这样就可以将错误向外传递。

  • 单元测试

    Rust中的单元测试使用上比较简单,#[test]即可开启测试,对于异步的测试,使用#[tokio::test]即可开启。需要注意的是,如果使用IDE点击运行开始测试的话,依赖的feature不会自动检测到,可能会报错,需要配置一下。其他测试库还没有常见用到,后续有用到了再补充。

  • 序列化/反序列化

    主要是指Json的序列化和反序列化,Java中有FastJson和Jackson,Rust中有serde_json。serde是一个通用的序列化和反序列化库,支持常见的Json、Yaml,但是好像不支持XML。使用上很简单,在struct上加上#[derive(Serialize, Deserialize)]即可支持序列化和反序列化,需要注意的是,struct里边的字段也需要支持序列化和反序列化,常用的基础数据类型是已经都实现了了的。

    可选项:serde、serde_json、serde_yaml

    除了Json外,还有protobuf,Rust也支持,叫做prost,可以很方便的进行encode和decode,它也支持从proto文件生成rs文件,构建工具叫做prost-build,我们可以在build.rs中配置需要生成的内容。

    还有arrow格式,这个是一种跨平台的数据格式,Rust也是支持的,如果需要跨进程传输数据,可以使用这个。

  • 消息队列

    消息队列也算是中间件,常用的kafka、rabbitmq、rocketmq等都有rust版的客户端实现。说到消息队列,除了这几个外,还有个库叫做zmq,用来做网络通信,也很不错,简单易用,支持多种TCP连接模式,也支持IPC,对于跨进程或者不同机器之间高效通信很适合。

    可选项:kafka、rabbitmq、rocketmq、zmq

  • 日志

    最后,就是日志库了,无论是Java还是Rust中,日志库都很多,Java中的Log4j可以对于Rust中的log库,都定义了统一的接口,有着不同的实现。常用的有env_logger、tracing、log4rs,tracing还未曾使用过,不过看介绍,似乎比较复杂一些,而env_logger则相对简单很多。env_logger支持不同级别的日志输出,支持按model过滤日志级别,支持彩色日志,但是,不支持输出到文件。所以log4rs可能更适合,它也支持通过yaml配置日志格式,支持不同的输出,支持滚动日志,看起来是比较适合web后端日志的。

    可选项:tracing、env_logger、log4rs

  • 其他

    除了以上了解到库外,还有其他一些使用到的库,也记录一下。

    • rand:随机数生成库
    • image: 图像处理
    • imageproc:实现了一些图像处理相关的算法
    • base64:base64编码解码
    • chrono:日期时间库,这个很常用,提供了大量的日期和时间操作API
    • once_cell:全局静态变量初始化。Rust中static类型不能像Java一样很方便的定义全局静态变量,这个库提供了简单的静态变量初始化方式,并且线程安全,确保只被初始化一次。
    • strum:枚举遍历以及枚举值映射
    • reqwest:用于简单的http请求
    • tokio-cron-scheduler:定时任务
    • dashmap:简化并发编程中的hashmap带来的问题

Rust做Web开发,有好处也有坏处,先说好处。首先确实能够节约机器成本,一个Rust包通常来说会比Jar包小很多,而运行时占用的内存就比Java小的更多了,能够减小5倍左右;其次,Rust写的程序,确实会比Java稳定,能够规避一些潜在的问题,例如NPE等,当然前提是不要到处unwrap,否则一样会崩。另外,对于客户端来说,Tauri使用Rust构架,如果做客户端开发,前端使用Vue,后端使用Rust还是很方便的。还有就是在部署层面,Rust可以跨平台编译,使用musl工具链编译后,基本上可以部署到任何linux系统上,对于需要支持不同平台的应用来说,非常方便,而对于Java来说还需要JVM的环境,虽然Java21已经支持原生应用编译了,但是依赖于泛型的框架来说,编译可能还是有些坑的。

再说不好的地方,一是学习成本,Rust的确没有Java容易学,尤其是对Java越熟悉的,转Rust可能反而会比较麻烦,因为很多概念两者并不相通,这是学习成本,并非开发成本,因为如果熟悉了Rust的话,开发速度其实并不慢,我们更多需要的是在开发初期做好设计,不论架构还是API,否则后续修改起来还是比较痛苦的。所以这也就是Rust做Web开发的另一个不好的地方,不能快速适应业务上的变化,由于本身的语法限制,你不能向Java一样运用各种设计模式来应对业务变化,而需要花费更多的时间去衡量是否需要重构或者其他方案,换句话说,可能对于我们做开发的要求会变高,考虑的东西也会变多,比如改用String还是&str?不过,从另一种角度看,这也提高了我们的编程的严谨性和系统的稳定性吧。

最近也在尝试使用Rust在嵌入式设备上部署例如Yolo等模型,以及一些大模型,想尝试使用ONNX简化部署流程,期间也遇到了很多问题,比如OpenCV交叉编译、Rust的交叉编译、FFI调用、跨进程通信等问题。看起来有点混乱,这些后续有时间再总结一下。本身是从5年的Java转Rust,目前看Rust国内只有量化和区块链这两个方向稍微多一点,其他的几乎没有岗位,也是一脸迷茫,期待后续Rust能够在不同领域发展起来,多一些工作机会吧。


http://www.ppmy.cn/server/175120.html

相关文章

前端构建工具进化论:从Grunt到Turbopack的十年征程

前端构建工具进化论:从Grunt到Turbopack的十年征程 一、石器时代:任务自动化工具(2012-2014) 1.1 Grunt:首个主流构建工具 // Gruntfile.js 典型配置 module.exports function(grunt) {grunt.initConfig({concat: {…

内网渗透之内网基础知识(一)

工作组 工作组:工作组是局域网中的一个概念,他是长久的资源管理模式。默认情况下使 用工作组方式进行资源管理,将不同的 computer 按照不同的要求分类到不同的组 域:用来描述一种架构,和“工作组”相对应,由工作组升级而来的高级…

【0x80070666】-已安装另一个版本...(Tableau 安装失败)

第一种是之前安装过tableau相关软件,但是没卸载干净。 方法1:卸载旧版本 打开 控制面板 → 程序和功能(或 添加/删除程序)。查找 Tableau Desktop,如果已安装旧版本,卸载它。重新启动电脑后再尝试安装。 …

【SpringMVC】常用注解:@RequestBody

1.作用 用于获取请求实体内容,直接使用得到的是keyvalue&keyvalue的数据。获取请求实体内容不适用get请求。 2.属性 required 描述是否有请求体,默认值为true。当取值为true时,get 请求方式会报错。如果取值为false,get请…

树莓派上的 TensorFlow Lite:从零开始的摄像头图像识别

**** 1. 引言 随着人工智能(AI)和机器学习(ML)的发展,越来越多的开发者希望在嵌入式设备(如树莓派)上运行 AI 模型,实现目标检测、人脸识别等功能。TensorFlow Lite(TF…

基于Hadoop的城市道路交通数据的可视化分析-Flask

开发语言:Python框架:flaskPython版本:python3.8数据库:mysql 5.7数据库工具:Navicat11开发软件:PyCharm 系统展示 管理员登录 管理员功能界面 数据信息管理 数据信息修改 搜索功能 公告展示界面 公告修改…

【生活好帮手】saas小程序,让线上服务触手可及。

在日常生活中,我们经常会遇到各种需要线上服务的场景。比如,想在周末宅家点一杯咖啡,或者预约一次健身课程,又或者为自己的小店搭建一个线上销售渠道。这时候,一个好用的小程序就成了我们的生活加速器。今天&#xff0…

树莓科技(成都)集团:如何铸就第五代产业园标杆

树莓科技(成都)集团铸就第五代产业园标杆,主要体现在以下几个方面: 精准定位与前瞻布局 树莓科技并非盲目扩张,而是精准锚定数字经济发展方向。以成都为起点,迅速构建起全国性的园区版图,体现…