话说我的公司只是一家名不见经传的小公司,这家公司的老板 John 又特别的抠搜。买的服务器的配置啊,那是低的可怜,云厂商大促的时候, 99 包年,内存只有可怜的 1GB。
但是 John 又志向远大,想要做一个网络文件的爬虫,爬取网络上形形色色的文件,比如某国的一些影视作品。这时候他就对我说:“小苏,给你一个任务,根据我给定的网址,帮我爬取一些影视作品”。我偷偷看了一下,好吧,这些作品可真是拍摄精良,成本巨大,少则 几个 G,多则几十个 G。
我无奈的对 John 说,这事情我干不了啊,服务器只有 1 个 GB 的内存,下载大文件会 OOM(Out Of Memory)啊。
老板挥挥手,不耐烦地说:”我不管,你自己想办法去”。说吧,转身带着他刚招聘的女秘书小米进入了办公室。
留下我一个人坐在工位上苦思冥想……1G内存,100G 的文件?如果直接使用 Rust 中的 Reqwest 库,可能不行,一次性将文件下载到内存中,肯定会 OOM!啊!我想到了,Reqwest 有一个特别棒的 future,使用 Stream!说干就干。
使用 Reqwest + Stream 下载大文件
心里想着,老板有了新的女同事,最近心情都好了不少。我想做完这个项目,老板说不一定一高兴,给我升职加薪,我就可以给他女儿买礼物了……想着想着,键盘都打地更欢快了。
使用 cargo 创建项目,声明依赖:
[dependencies]
reqwest = { version = "0.12.15", features = ["json", "multipart", "stream"] }
tokio = { version = "1.45.1", features = ["full"] }
futures-util = "0.3.31"然后快速写了一个 demo,老板要是中午前还看不上这些作品,说不定会 emo:
use futures_util::StreamExt;
use reqwest::Client;
use tokio::fs::File;
use tokio::io::AsyncWriteExt;
#[tokio::main]
async fn main() {
let url = "https://x.com/large_video.mp4";
let mut stream = Client::new().get(url)
.send()
.await
.unwrap()
.bytes_stream();
let mut file = File::create("large_video.mp4").await.unwrap();
while let Some(chunk) = stream.next().await {
let chunk = chunk.unwrap();
file.write_all(&chunk).await.unwrap();
}
}啊!大功告成!使用 Stream 之后,Chunk by chunk 就不会 OOM 啦!
我兴冲冲地走进了办公室,老板喜上眉梢地看着我:小苏,那么快就完成啦?我说是的。给你演示一下哈!没想到,演示现场就是大型车祸现场。内存 1GB 是够了,磁盘只有 20GB 根本不够!
老板皱起了眉头,说道:小苏啊,你怎么那么粗心,没考虑到磁盘不够?我这里有一台客户的服务器,磁盘狗够够的,你上传到他们服务器吧……我心里万马奔腾……这也行?
使用 Reqwest + Multipart 上传大文件
不过话说起来,这个客户一如我们对甲方爸爸的想象,超级富有。一次性购入百万的服务器以及网络设备,运行着一个 RPS 只有不到 100 的项目,据说还投入了上千万的研发费用,然后层层外包到我们这个互联网小作坊。
嗯,这是题外话,还是干活吧,John 的女儿还是等我送端午节的礼物呢:
use reqwest::Client;
#[tokio::main]
async fn main() {
let form = reqwest::multipart::Form::new()
.text("title", "large_video")
.part("file", reqwest::multipart::Part::file("large_video.mp4").await.unwrap());
Client::new().post("https://rich_customer.com")
.multipart(form)
.send().await.unwrap();
}很快也写好了,Reqwest 已经封装好了 Multipart 的特性,写起来也真是 So easy。也许今年年底,妈妈就不需要催婚了,从此可以过上不 emo 的生活了。
后续
走进老板办公室,再次演示了我这个小项目。大概半小时后,我红着脸走出了办公室…..老板怎么不夸我呢?入职的时候说好的升职加薪呢?难道是因为我知道太多了?