笔记在github,觉得有用的给个 Star 。
此笔记只是记录在使用 rust 遇到的一些坑或者一些比较好用的工具或者其他的东东。本人主要用 rust 开发网络相关的程序或者桌面程序,因此不涉及音视频和其他的领域。
cross:跨平台编译,甚至在 github actions 也可以直接用cross。
tarpaulin:单元测试覆盖率。
min-sized-rust:减少编译后的二进制文件大小。
常用的 tokio 异步运行时不多说了。http web 框架可能有争议,比如 warp,actix-web 可能性能会好一点,但是 axum 写起来更简单。sqlx 虽然直接写 sql ,相信我,其他的 ORM 框架更难用!
tracing:tokio 的日志模块,非常强大,在 tokio 运行时中强烈建议使用 tracing 配合 tracing-appender 做日志。
hyper:开发底层 http1 、http2 必备的 crates 。
axum:http web 框架,CRUD boy 必备。
sqlx:sqlx 框架,CRUD boy 必备。
reqwest:http client 。
clap:开发终端工具/命令行程序必备。
openssl:openssl 相关,由于很多 crate 是基于 openssl 的,一般都是作为 vendor 引入编译的时候直接一起编译。
如果用 rust 做 web 程序,根本用不到生命周期。我至今还不懂生命周期,照样用 rust 开发 web ,技术栈就是 axum+tracing+sqlx+reqwest 。
先说答案,默认的 allocator ,在并发数升高后会导致内存飙升,且并发数降低时,内存不会降低。当前的解决方案是使用 MiMalloc(本人已经验证过,效果良好)。具体的问题讨论在这里。
互斥锁并不慢,我使用互斥锁来存储 redis 的所有数据,最后多线程的压测结果,rcache 的吞吐量是 redis 的两倍。
先说结果,不一定,而且异步的程序相比同步的程序肯定要慢的。
什么时候使用异步运行时开发呢?
什么时候使用同步运行时开发程序呢?
常用场景:我看 tokio 里面有 Mutex 我就直接用了,没想那么多。
这个 Mutex 的性能很低,相比 std::sync::Mutex 性能低一倍以上。如果对性能敏感的应用可以直接在异步运行时中使用 std::sync::Mutex 。感兴趣的可以看一下 tokio 的关于 Mutex 的文档。压测的程序在这里.但是在异步运行时中使用 std 的 Mutex 时需要注意的原则是“锁保护的代码段不跨越 await”。
let a=b.await?;
let c=a.read().await?;
let c=b.and_then(|d|d.read()).await?
看上去第二种写法只 await 一次,其实如上两种写法性能上没有本质差别,第二种写法只是使用了 future 这个 crates 提供的内部的状态机。
1
wikilab 136 天前 via Android
多谢分享
|
2
imMetaverse 136 天前
多谢分享
|
3
yazoox 136 天前
> MiMalloc
我看你链接的帖子里,好像只有一个人使用这个工具有效,其他人都没有效果。 你能多分享一些你使用的心得和技巧么? thx |
4
ch3nOr 136 天前
多谢分享
|
5
daniel11 136 天前
多谢分享 想了解下是什么背景情况下选择用 Rust 的 axum+tracing+sqlx+reqwest 开发 web 程序的
|
6
changdig 136 天前
多谢,对于 rust 开发 web 还是有点犹豫,感觉没啥必要
|
7
445141126 136 天前
@yazoox 应该是有效果的
> I was having the same issue and switched to the MiMalloc allocator. It releases memory instantly - from 2GB when underload back to 50MB when idle, constrast to the default allocator which peaks at 3GB and 1.7GB when idle. MiMalloc does not only consume less memory but also performs better in my case, bench tested both on my Linux machine and Docker container with resource limited to 1CPU 1GB. I think I'm going to stick with MiMalloc for now. |
8
lsk569937453 OP @yazoox 直接全局修改 allocator 即可,就加两行代码。
#[global_allocator] static GLOBAL: MiMalloc = MiMalloc; 测试的场景是:先把压测工具的并发数设置为 2000 ,此时 hyper 进程占用的内存是 1G 。然后将并发数设置为 200 ,此时 hyper 的内存降低为 80M 。测试完成。 |
9
hasdream 136 天前
多谢分享
|
10
OBJECTION 136 天前
最近也是闲着无聊再看 rust 先收藏了
|
11
xiangchen2011 136 天前
写的挺好的
|
12
Cambra1n 136 天前
谢谢分享,最近也想学习学习,但不清楚在后端和大数据中间件方面有哪些优势。
|
13
artiga033 136 天前 via Android
sqlx 直接写 sql 还是有点无法接受,一般我宁愿选择 mongoDB 。
个人推荐个 ORM 框架 sea-orm,底层是 sqlx ,可以用 rust 写数据库的迁移文件,整体体验和.NET 的 entity framework 很类似 |
14
PTLin 135 天前
补充一下,现代的 Mutex 其实内部都会自旋一段时间,获取不到锁并不会直接进行系统调用而休眠,因为现在处理器速度非常快,很多时候自旋的时候锁就被释放了。
tokio 的 Mutex 使用原则基本上是:假如是多 task 操作一个 Vec 那种,临界区非常小,并且不跨越 await (因为 await 点可能出现一个线程加锁,另一个线程释放的问题,所以 std Mutex guard 是!Send ,导致整个 future 都是!Send) ,直接用 std 的 Mutex 就好。但是假如是独占了一个需要长时间使用数据,例如异步的数据库链接,这种才需要使用 tokio Mutex 。 |
15
tairan2006 133 天前
感觉学 rust 用来写 web 真的是浪费时间……
|