在本文中,我将比较 Deno 的原生 HTTP 服务器和 Rust 的 Hyper HTTP 服务器。根据我的研究,我发现 Hyper 是 Rust 方面最受欢迎的服务器选择。如果有更好和流行的替代品,请告诉我。

这种比较很有趣,因为 Deno 本身是用 Rust 编写的。这种比较可能没有多大意义,因为 Rust 应该很容易胜过 Deno。主要区别在于Deno使用不同的HTTP服务器,称为flash。让我们运行测试并检查结果。

在继续之前,其他比较如下:

测试设置

这些测试在具有16G RAM的MacBook Pro M1上执行。

软件版本为:

  • Deno v1.32.3
  • Rust v1.68.2

在这两种情况下,hello world HTTP 服务器代码如下所示:

Deno

Deno.serve((_) => new Response("Hello world!"), {
  port: 3000,
});

Rust

use std::convert::Infallible;
use std::net::SocketAddr;

use bytes::Bytes;
use http_body_util::Full;
use hyper::server::conn::http1;
use hyper::service::service_fn;
use hyper::{Request, Response};
use tokio::net::TcpListener;

async fn hello(_: Request<hyper::body::Incoming>) -> Result<Response<Full<Bytes>>, Infallible> {
  let response = Response::builder()
    .header("Content-type", "text/plain")
    .body(Full::new(Bytes::from("Hello World!")))
    .unwrap();
  Ok(response)
}

#[tokio::main]
pub async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
  let addr: SocketAddr = ([127, 0, 0, 1], 3000).into();
  let listener = TcpListener::bind(addr).await?;
  loop {
    let (stream, _) = listener.accept().await?;
    tokio::task::spawn(async move {
      if let Err(err) = http1::Builder::new()
        .serve_connection(stream, service_fn(hello)).await {
          println!("Error serving connection: {:?}", err);
        }
    });
  }
}

Cargo.toml

[package]
name = "hello_world"
version = "0.1.0"
edition = "2021"

[dependencies]
bytes = "1"
hyper = { version = "1.0.0-rc.3", features = ["full"] }
tokio = { version = "1", features = ["full"] }
http-body-util = "0.1.0-rc.2" 

运行测试

每个测试针对 5M(500 万个)请求执行。

对 10、100 和 300 个并发连接执行测试。

负载测试是使用 Bombardier HTTP测试工具进行的。

下表显示了每个并发级别的结果:

10 concurrent connections 100 concurrent connections 300 concurrent connections

分析

我对结果感到非常惊讶。Deno 在强大的 Rust 面前。在低并发时,RPS 和延迟数字几乎相同。显着的区别在于内存使用,Rust 几乎不使用任何东西。在高并发性下,Rust 提供 173K,而 Deno 提供 165K。这不是一个很大的区别。Deno 的 CPU 使用率较低,而 Rust 的内存使用率非常少。

获胜者:很难说,但我会选择Rust

同样,其他比较是: