我需要向同一服务器发出一长串REST调用(我们称其为myapi.com
)。目前,我使用Rust库reqwest
如下所示:
- 我创建一个
reqwest::Client
与所有默认设置。 - 对于每个REST调用:
- 我使用
client.post("https://myapi.com/path/to/the/api")
创建reqwest::RequestBuilder
。 - 我配置
RequestBuilder
获取reqwest::Request
。 - I
send()
和Request
,读取reqwest::Response
。 - 我放下除了
Client
之外的所有东西,重新开始。
- 我使用
我在文档中读到reqwest
应该在相同的Client
内池连接。考虑到我总是重用相同的Client
,我希望第一个API调用花费更多的时间(由于初始的TCP和HTTPS握手)。然而,我观察到所有请求都有一致的、相当高的延迟。所以,我想知道连接是否被重用,或者每次都重新建立。如果它们不是,我如何得到回收相同的连接?我觉得如果我能节省一些往返时间,延迟会大大减少。
行为取决于你是使用reqwest::blocking::Client
(同步)还是reqwest::Client
(异步)。
是否重用现有的连接可以通过启用调试日志来检查。
reqwest::blocking::Client
当使用同步API时,仅仅重用客户端就意味着重用连接。
这是因为,在我们第二次(或第三次或…)使用客户端时,它保证第一次调用已经完成,并且我们有一个连接。
use std::env;
use reqwest::blocking::Client;
fn main() {
env::set_var("RUST_LOG", "debug");
env_logger::init();
let client = Client::new();
for _ in 0..3 {
//calls an API which returns a random string
let res = client
.get("https://ciprand.p3p.repl.co/api?len=10&count=1")
.send()
.unwrap();
println!("{}", res.text().unwrap());
}
}
[2023-05-17T07:11:13Z DEBUG reqwest::connect] starting new connection: https://ciprand.p3p.repl.co/
{"Strings":["fa749eda765"],"Count":1,"Length":10}
{"Strings":["dd0a8bfdc57"],"Count":1,"Length":10}
{"Strings":["cdedd8e3982"],"Count":1,"Length":10}
(只打印一个starting new connection
)
reqwest::Client
当使用异步API时,只重用客户端NOT意味着重用连接。
这是因为,在我们第二次(或第三次或…)使用客户端时,它是而不是保证第一个呼叫已经完成并且我们有一个连接。
(下面的代码是为了实验目的:永远不要写这样的异步代码)
use std::{env, sync::Arc};
use reqwest::Client;
async fn call(url: &str, client: Arc<Client>) {
client.get(url).send().await.unwrap();
println!("completed");
}
#[tokio::main]
async fn main() {
env::set_var("RUST_LOG", "debug");
env_logger::init();
let client = Arc::new(Client::new());
for _ in 0..2 {
tokio::spawn(call(
"https://ciprand.p3p.repl.co/api?len=10&count=1",
client.clone(),
));
}
std::thread::sleep(std::time::Duration::from_millis(1000));
for _ in 0..2 {
tokio::spawn(call(
"https://ciprand.p3p.repl.co/api?len=10&count=1",
client.clone(),
));
}
std::thread::sleep(std::time::Duration::from_millis(1000));
}
[2023-05-17T07:14:25Z DEBUG reqwest::connect] starting new connection: https://ciprand.p3p.repl.co/
[2023-05-17T07:14:25Z DEBUG reqwest::connect] starting new connection: https://ciprand.p3p.repl.co/
completed
completed
completed
completed
(只打印两个starting new connection
。这是因为,在第三次和第四次使用客户端时,第一次(或第二次)调用偶然地完成了,并且我们建立了连接。