[步入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测试结果:

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。