Skip to content

Commit

Permalink
feat: optimize server and document
Browse files Browse the repository at this point in the history
  • Loading branch information
0xAlcibiades committed Sep 12, 2024
1 parent ff7b439 commit 968a496
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 544 deletions.
8 changes: 5 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ http = "1.1.0"
http-body = "1.0.1"
http-body-util = "0.1.2"
hyper = "1.4.1"
hyper-rustls = { version = "0.27.3", features = ["http2"] }
hyper-util = { version = "0.1.8", features = ["server", "tokio", "server-auto", "server-graceful", "service"] }
pin-project = "1.1.5"
rand = "0.9.0-alpha.2"
Expand All @@ -40,13 +39,16 @@ pprof = { version = "0.13.0", features = ["flamegraph"], optional = true}

[dev-dependencies]
criterion = { version = "0.5.1", features = ["html_reports", "async_tokio"] }
hyper-rustls = { version = "0.27.3", features = ["http1", "http2"] }
hyper-util = { version = "0.1.8", features = ["client", "client-legacy", "http2"] }
hyper = { version = "1.4.1", features = ["client"] }
tokio = { version = "1.40", features = ["rt", "net", "test-util"] }
tokio = { version = "1.40", features = ["rt-multi-thread", "net", "test-util", "time"] }
tokio-util = { version = "0.7.12", features = ["compat"] }
tracing-subscriber = "0.3.18"
num_cpus = "1.16.0"
ring = "0.17.8"
rcgen = "0.13.1"
reqwest = { version = "0.12.7", features = ["rustls-tls", "http2"] }

[[bench]]
name = "hello_world_tower_hyper_tls_tcp"
Expand All @@ -58,4 +60,4 @@ jemalloc = ["tikv-jemallocator"]
dev-profiling = ["pprof"]

[profile.release]
debug = true
debug = true
71 changes: 43 additions & 28 deletions benches/hello_world_tower_hyper_tls_tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,14 @@ use std::sync::Arc;
use bytes::Bytes;
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
use http::{Request, Response, StatusCode, Uri};
use http_body_util::{BodyExt, Empty, Full};
use http_body_util::{BodyExt, Full};
use hyper::body::Incoming;
use hyper_rustls::HttpsConnectorBuilder;
use hyper_util::client::legacy::Client;
use hyper_util::rt::TokioExecutor;
use hyper_util::server::conn::auto::Builder as HttpConnectionBuilder;
use hyper_util::service::TowerToHyperService;
use rcgen::{CertificateParams, DistinguishedName, KeyPair};
use rustls::crypto::aws_lc_rs::Ticketer;
use reqwest::Client;
use rustls::crypto::aws_lc_rs::{default_provider, Ticketer};
use rustls::pki_types::{CertificateDer, PrivatePkcs8KeyDer};
use rustls::server::ServerSessionMemoryCache;
use rustls::{ClientConfig, RootCertStore, ServerConfig};
Expand Down Expand Up @@ -275,25 +274,19 @@ async fn start_server(
}

async fn send_request(
client: &Client<
hyper_rustls::HttpsConnector<hyper_util::client::legacy::connect::HttpConnector>,
Empty<Bytes>,
>,
client: &Client,
url: Uri,
) -> Result<(Duration, usize), Box<dyn std::error::Error + Send + Sync>> {
let start = Instant::now();
let res = client.get(url).await?;
let res = client.get(url.to_string()).send().await?;
assert_eq!(res.status(), StatusCode::OK);
let body = res.into_body().collect().await?.to_bytes();
let body = res.bytes().await?;
assert_eq!(&body[..], b"Hello, World!");
Ok((start.elapsed(), body.len()))
}

async fn concurrent_benchmark(
client: &Client<
hyper_rustls::HttpsConnector<hyper_util::client::legacy::connect::HttpConnector>,
Empty<Bytes>,
>,
client: &Client,
url: Uri,
num_requests: usize,
) -> (Duration, Vec<Duration>, usize) {
Expand Down Expand Up @@ -322,22 +315,46 @@ async fn concurrent_benchmark(
}

fn bench_server(c: &mut Criterion) {
let server_runtime = Arc::new(create_optimized_runtime(num_cpus::get() / 2).unwrap());
let bench_runtime = create_optimized_runtime(num_cpus::get() / 2).unwrap();

let (server_addr, shutdown_tx, client) = bench_runtime.block_on(async {
// Install the default provider for AWS LC RS crypto
default_provider().install_default().unwrap();

let (server_addr, shutdown_tx, client) = server_runtime.block_on(async {
let tls_config = generate_shared_ecdsa_config();
let (server_addr, shutdown_tx) = start_server(tls_config.server_config.clone())
.await
.expect("Failed to start server");
info!("Server started on {}", server_addr);

let https = HttpsConnectorBuilder::new()
.with_tls_config(tls_config.client_config)
.https_or_http()
.enable_http1()
.build();

let client: Client<_, Empty<Bytes>> = Client::builder(TokioExecutor::new()).build(https);
// Unfortunately hyper based http2 seems pretty busted here
// around not finding the tokio runtime timer
// https://github.com/rustls/hyper-rustls/issues/287
// let https = HttpsConnectorBuilder::new()
// .with_tls_config(tls_config.client_config)
// .https_or_http()
// .enable_all_versions()
// .build();
//
// let client: Client<_, Empty<Bytes>> = Client::builder(TokioExecutor::new())
// .timer(TokioTimer::new())
// .pool_timer(TokioTimer::new())
// .build(https);

let client = reqwest::Client::builder()
.use_rustls_tls()
// This breaks for the same reason that the hyper-tls/hyper client does
//.http2_prior_knowledge()
// Increase connection pool size for better concurrency
.pool_max_idle_per_host(1250)
// Enable TCP keepalive
.tcp_keepalive(Some(Duration::from_secs(10)))
// Disable automatic redirect following to reduce overhead
.redirect(reqwest::redirect::Policy::none())
// Use preconfigured TLS settings from the shared config
.use_preconfigured_tls(tls_config.client_config)
.build()
.expect("Failed to build reqwest client");

(server_addr, shutdown_tx, client)
});
Expand All @@ -358,8 +375,7 @@ fn bench_server(c: &mut Criterion) {
group.bench_function("serial_latency", |b| {
let client = client.clone();
let url = url.clone();
let client_runtime = create_optimized_runtime(num_cpus::get() / 2).unwrap();
b.to_async(client_runtime)
b.to_async(&bench_runtime)
.iter(|| async { send_request(&client, url.clone()).await.unwrap() });
});

Expand All @@ -373,8 +389,7 @@ fn bench_server(c: &mut Criterion) {
|b, &num_requests| {
let client = client.clone();
let url = url.clone();
let client_runtime = create_optimized_runtime(num_cpus::get() / 2).unwrap();
b.to_async(client_runtime).iter(|| async {
b.to_async(&bench_runtime).iter(|| async {
concurrent_benchmark(&client, url.clone(), num_requests).await
});
},
Expand All @@ -383,7 +398,7 @@ fn bench_server(c: &mut Criterion) {

group.finish();

server_runtime.block_on(async {
bench_runtime.block_on(async {
shutdown_tx.send(()).unwrap();
tokio::time::sleep(Duration::from_secs(1)).await;
});
Expand Down
Loading

0 comments on commit 968a496

Please sign in to comment.