[步入rust]从零开始进入Warp-初步接触

2021 年 1 月 8 日 星期五(已编辑)
/ ,
100
这篇文章上次修改于 2024 年 6 月 1 日 星期六,可能部分内容已经不适用,如有疑问可询问作者。

[步入rust]从零开始进入Warp-初步接触

简介

warp是一个异步IO构建的Web框架,超级易于使用和简洁。并且由于其作者也是开发了hyper开发者,因此warp在Rust社区中有不错的热度。

并且由于独特的提供了其他Rust Web框架没有的Filter系统,所以以下组件开箱可用:

  • Path routing and parameter extraction / 路径路由及参数析出
  • Header requirements and extraction / Header参数析出
  • Query string deserialization / Query字符串反序列化
  • JSON and Form bodies / JSON和表单
  • Multipart form data / Multipart表单
  • Static Files and Directories / 静态文件和路径映射
  • Websockets
  • Access logging / 请求日志
  • Etc

底层的如下组件由hyper提供:

  • HTTP/1
  • HTTP/2
  • Asynchronous / 异步
  • One of the fastest HTTP implementations / 最快的HTTP实现之一
  • Tested and correct / 代码测试

快速使用

引用库

warp基于hyper基于tokio异步库所以也要加入

toml: tokio = { version = "0.2.5", features = ["full"] } warp = "0.2.5"

编写代码

use warp::{Filter};

#[tokio::main]
async fn main() {
    // 注册filter
    let hello_path_echo = warp::any().and(warp::path!("hello_pa"/String)).map(|str:String|format!("hello {}",str));
    let hello = warp::any().and(warp::path("hello")).map(||format!("hello"));
    // 注册全部路由
    let route = hello.or(hello_path_echo);
    // 启动Web
    warp::serve(route).run(([127, 0, 0, 1], 3030))
        .await;
}

访问3030:/hello和3030:/hello_pa/image来查看结果 在此可以窥见filter的简易之处,可以使用and来拼接该api需要的一切东西,但是本篇先不进行语法和设计讲解。

性能测试

Rust作为“下一代的C++”怎么不可能会没有性能上的比较呢。所以在此选择本人会的Python-Flask,Java-Spring作为比较对象。

全部最小实现去除访问日志输出和仅实现hello和hello_pa接口,使用wrk进行并发测试。

测试配置

目标机器配置:e5 2678v3 * 24 核心 + 32G内存 + 1G 网卡 wrk机器:i7 6700 6c/12t + 16G内存 + 1G 网卡 wrk参数:./wrk -c1000 -t12 -d30s --latency http://ip:3030/hello

测试结果

刚开始被测端和测试端都在一台电脑上,发现很容易影响真实性能,所以最后放到服务器上测试。

Java+Spring测试结果: bash Running 30s test @ http://192.168.1.40:8080/hello 12 threads and 1000 connections Thread Stats Avg Stdev Max +/- Stdev Latency 22.89ms 10.92ms 387.61ms 98.56% Req/Sec 3.62k 448.78 5.48k 93.56% Latency Distribution 50% 21.97ms 75% 23.40ms 90% 25.39ms 99% 36.13ms 1289844 requests in 30.10s, 145.38MB read Socket errors: connect 0, read 0, write 0, timeout 20 Requests/sec: 42852.37 Transfer/sec: 4.83MB Rust+warp release测试结果 image@DESKTOP-LCQEVKO:/mnt/c/Users/Image/Documents/wrk$ ./wrk -c1000 -t12 -d30s --latency http://192.168.1.40:3030/hello Running 30s test @ http://192.168.1.40:3030/hello 12 threads and 1000 connections Thread Stats Avg Stdev Max +/- Stdev Latency 20.31ms 7.03ms 317.98ms 98.90% Req/Sec 4.10k 166.88 6.09k 93.64% Latency Distribution 50% 20.10ms 75% 20.71ms 90% 21.35ms 99% 23.83ms 1471946 requests in 30.08s, 169.85MB read Requests/sec: 48938.95 Transfer/sec: 5.65MB Rust+warp debug测试结果: Running 30s test @ http://192.168.1.40:3030/hello 12 threads and 1000 connections Thread Stats Avg Stdev Max +/- Stdev Latency 20.35ms 3.11ms 50.95ms 79.34% Req/Sec 4.06k 168.58 6.37k 82.47% Latency Distribution 50% 20.15ms 75% 21.61ms 90% 23.58ms 99% 31.18ms 1456599 requests in 30.07s, 168.08MB read Requests/sec: 48435.94 Transfer/sec: 5.59MB Python+Flask测试结果 Running 30s test @ http://192.168.1.40:5000/hello 12 threads and 1000 connections Thread Stats Avg Stdev Max +/- Stdev Latency 147.88ms 151.79ms 1.02s 91.21% Req/Sec 101.09 38.31 380.00 67.30% Latency Distribution 50% 107.74ms 75% 110.00ms 90% 114.73ms 99% 1.01s 36146 requests in 30.05s, 5.41MB read Socket errors: connect 0, read 339, write 83, timeout 642 Requests/sec: 1202.73 Transfer/sec: 184.40KB

Rust+warp在高并发测试下无论Debug或是Release下均超过了Java+Spring的测试成绩,同时吊打Flask(编译型语言不能吊打解释型那就有鬼了)

看到这个结果也许有人会说Java+Spring这么重个框架也就跟warp差了20%而已。然而需要说明的是warp和Flask都仅占用了100%的CPU性能,而Java+Spring最高使用了500%的CPU性能。因此可以在相同的配置下甚至可以开5个warp应用来抗并发,这样算下来warp对简单的Http请求处理就有Java+Spring 5到6倍的req/sec。

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...